2012-07-31 3 views
2

사이의 통신 나는이 두 가지 방법으로 주문 확인 및 WCF 서비스를 요청하는 WCF 클라이언트 :WCF - 두 가지 방법

1) UpdateOrder - 업데이트가 데이터베이스의 데이터를 (UpdateOrder 호출이 외부 서비스에서 제공) 주문
2) GetConfirmationResult - 주문 상태가 대기 중 상태에서 다른 상태로 바뀔 때까지 결과를 반환합니다.

질문 : WCF에서 UpdateOrder에서 GetConfirmationResult로 알림을 보내면 주문 상태가 어떻게 변경됩니까?

업데이트 : InstanceContextMode를 Per-Call로 남겨 둘 수 있다면 가장 좋을 것입니다.

업데이트 2 : 가능한 주문 상태가 보류 중, 확인 됨, 거부 됨이라고 가정 해 봅시다. ConfirmOrder는 주문 상태를 Confirmed 또는 Rejected로 변경할 수 있습니다. GetConfirmationResult는 Confirm 주문으로 변경 될 때까지 결과를 반환하지 않아야합니다.

업데이트 3 : 전체 스택을 표시하기 위해 시퀀스로 이미지를 변경했습니다.

enter image description here

+0

주문 방법은 편도입니까? 어떤 교통 수단을 사용하고 있습니까? –

+0

@hugh : 주문 방법이 한 가지 방법이며, 전송은 https입니다. – Giedrius

+1

또한 귀하의 클라이언트가 귀하의 서비스와 동일한 네트워크에서 GetConfirmationResult를 호출합니까? –

답변

1

현재 EventWaitHandle을 사용하여 해결했습니다. - 이것이 최선의 방법인지 확실하지 않지만, 꽤 깨끗하게 보입니다. 타임 아웃을 능숙하게 지원하며, 꽤 테스트 할 만합니다.

public class TestClass 
{ 
    public static event OrderUpdateHandler UpdatedOrder; 

    public void UpdateData(Order order) 
    { 
     // ... 

     OnOrderUpdated(args); 
    } 

    public Order GetConfirmedOrder(int id, TimeSpan waitToConfirm) 
    { 
     var order = GetOrderFromDatabase(); 

     if (order.Status == OrderStatus.Pending) 
     { 
      var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 

      UpdatedOrderHandler waiter = (s, e) => 
      { 
       if (e.Order.Id == id) 
       { 
        order = e.Order; 
        eventHandle.Set(); 
       } 
      }; 

      UpdatedOrder += waiter; 

      if (!eventHandle.WaitOne(waitToConfirm)) 
      {     
       return order; 
      } 

      OrderUpdated -= waiter; 
     } 

     return order; 
    } 
} 
+0

좋은 정보! 이것이 해결책이라면 대답으로 표시하십시오. 건배 –

3

당신은이 서버를 백업 데이터베이스가 말한다. 그 다음이, 반 사이비처럼 간단 수 있습니다 :

public YourService : YourServiceInterface 
{ 
    public void UpdateOrder(Order order) 
    { 
     using (context = new DatabaseContext()) 
     { 
      context.Orders.Where(o => o.ID == order.ID).First().IsConfirmed = order.IsConfirmed; 
      context.SaveChanges(); 
     } 
    } 

    public Boolean? GetConfirmationResult(Order order) 
    { 
     using (context = new DatabaseContext()) 
     { 
      return context.Orders.Where(o => o.ID == order.ID).First().IsConfirmed; 
     } 
    } 
} 

당신은 통화 당 인스턴스 모드를 언급하고 있기 때문에, 그것을 유지해야합니다. static List<Order>에 보류중인 주문을 보관할 수 없으며 데이터베이스에 보관하고 승인되지 않은 보류 중으로 추가하기 만하면됩니다.

+0

필자는 GetConfirmationResult가 순간 주문 상태가 보류에서 다른 것으로 바뀔 때까지 결과를 유지한다고 언급 했으므로 솔루션에서 GetConfirmationResult를 쿼리하고 ConfirmOrder가 아직 주문을 업데이트하지 않은 경우 결과가 반환되지만 그렇지 않아야합니다. 이 질문을 좀 더 명확하게 업데이트했습니다. – Giedrius

+0

@Giedrius 나는 당신이 무엇을 의미하는지 모르겠다. _ "결과가 반환되지만,"_하지 않아야한다. 주문이 아직 확인되지 않았 으면 무엇을하기를 원합니까? 내 경우에는'false'를 반환합니다. – CodeCaster

+0

Thread.Sleep 나는 추측한다 : 그 결과는 웹 애플리케이션에 필요하므로 여러 가지 해결책이있다. 우리는 확인이 일어 났음을 알게 될 때까지 wcf에 대한 요청을 반복하거나 wcf면에서 결과를 발행하는 것을 지연시킬 수있다. . – Giedrius

1

문제는 사용자가 특정 시간에 주문 상태가 변경되고 해당 단계 변경이 발생하는 경우에만 서비스 이용자가 새로운 주문 상태에 대해 알 수 있다는 사실을 기반으로합니다.

이것은 메시징을 사용하는 완벽한 시나리오입니다.

wcf 클라이언트가 서비스를 호출하는 대신 서비스는 주문 상태가 변경되면 클라이언트에 메시지를 보내야합니다. 그런 다음 클라이언트는 메시지를 처리 ​​할 수 ​​있습니다 (사용자의 경우 ConfirmationResult 메시지).

netmsmqBinding을 사용하여이 작업을 수행하고 msmq 메시지를 허용하는 클라이언트에서 작업을 호스트 할 수 있습니다.

[OperationContract] 
void ReceiveConfirmationResult(ConfirmationResult result); 

이것은 문제의 원인을 완전히 제거하기 때문에 훨씬 간단합니다. 서비스 운영 GetConfirmationResult()는 더 이상 필요 없으므로 제거 할 수 있습니다.

UPDATE

나는 최신 질문 업데이트에 따라이 대기열을 사용하기위한 더 강한 경우가 있기 때문에 당신이 오해 생각합니다.이벤트의

주문 :

  1. 주문 확인은 서버 상태 서버가 상태 변경이 서버가 보내는 클라이언트
  2. 로 전송하는 경우는 운동하는 논리를 적용
  3. 변경
  4. 접수 상태 변경을 설명하는 클라이언트에 대한 메시지
+0

전적으로 동의하지만, 왜 긴 폴링 (또는 http://en.wikipedia.org/wiki/Comet_(programming))을 피하려고 노력해야하는지 이해하지 못합니다 – Giedrius

+0

그것은 복잡하기 때문에. 큐잉은 정말 간단합니다. 또한 가용성 및 내구성과 같은 다른 이점을 얻을 수 있습니다. 당신이 인터넷을 통해 가야한다면, 나는 혜성이나 다른 긴 폴링 전략이 최선의 방법 일 것이라고 동의 할 것입니다. –

+0

나는 약간의 생각을 해왔고 내 경우에는 메시징을 사용하여 WCF 응용 프로그램에서 클라이언트 (ASP.NET MVC) 응용 프로그램으로 만 문제가 옮겨 졌을 것이라고 생각합니다. 왜 그런지를 보여주기 위해 제 질문을 업데이트하려고합니다. – Giedrius

관련 문제