简体   繁体   中英

WCF - communication between two methods

I have a WCF client, that asks for order confirmation and WCF service with two methods:

1) UpdateOrder - updates order data in database (UpdateOrder call comes from external service)
2) GetConfirmationResult - which holds return of result till order status will change from pending to something else.

Question is, how to make notification from UpdateOrder to GetConfirmationResult, that order status has changed, in WCF?

Update: would be best, if I could leave InstanceContextMode as Per-Call.

Update 2: Let's say possible order statuses are Pending, Confirmed, Rejected. ConfirmOrder may change order status to Confirmed or Rejected, GetConfirmationResult should not return result until it is changed by Confirm order.

Update 3: I've changed image with sequence to display whole stack.

在此处输入图片说明

You say you have a database backing this server. Then it'll be as simple as this, semi-psuedo:

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;
        }
    }   
}

You'll have to persist it, since you're mentioning a per call instance mode. You can't keep a static List<Order> to contain your pending orders, simply persist them to your database and add them as pending, not approved.

It sounds like your problem is based on the fact that the order state changes at certain times and only when that stage change happens is it relevant for the service consumer to know about the new order state.

This is a perfect scenario for using messaging.

Rather than your wcf client calling the service, the service should just send a message to the client when the state of the order changes. The client can then process the message (in your case a ConfirmationResult message).

You can do this by using the netMsmqBinding and host an operation on the client which accepts a msmq message.

[OperationContract]
void ReceiveConfirmationResult(ConfirmationResult result);

This is far simpler as it removes the source of your problem entirely. As an added benefit the service operation GetConfirmationResult() can be removed as it is no longer needed.

UPDATE

I think you misunderstand because based on your latest question update this is an even stronger case for using queueing.

Order of events:

  1. Order confirmation received
  2. The server state changes
  3. The server applies logic to work out if a state change should be sent to the clients
  4. The Server sends a message to the client describing the state change

At the moment I've solved it using EventWaitHandle - not sure if it is the best way, but it looks quite clean, nicely supports timeout and is quite testable.

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM