WCF - client callback recommended?

丶灬走出姿态 提交于 2019-12-11 01:52:42

问题


I have one WCF service that exposes two operations - IncrementList() and GetList(). Client B connects to the service, calls GetList() and displays to the user. Client A has the ability to update this list by calling IncrementList().
I want Client B to get notified when IncrementList() is called so it can call GetList() again to display the updated data.

Could you please outline how you'd implement this? CallBacks? Duplex? Publisher/Subscriber?
Anything new in WCF 4.0 that aids in this scenario?

Thanks!


回答1:


Something you should decide up front is if you want to push the whole list when its incremented (heavy) or just the updated item to each client. The code below is for push whole list but easy to modify this just to push the updated object (recomended).
At app start Client B should call Register_client and then GetList. Subsequently it will be notified via call back when list is incremented (the client needs to implient this interface)
The call GetList requires a duplex channel and SessionMode.Required.

Your server should impliment:

[ServiceContract(SessionMode = SessionMode.Required
                 CallbackContract = typeof(IMyCallback))]
    public interface IMyServer {

    [OperationContract]
    void Register_client();

    [OperationContract(IsOneWay = true)]
    void IncrementList();

    [OperationContract]
    ListObject[] GetList();
}  

[DataContract]
public class ListObject {
    [DataMember]...
}

Your client should impliment:

public interface IMyCallback {
    [OperationContract(IsOneWay = true)]
    void PushList(ListObject[] list);
}

Register client just needs store client callback interface for use when list is incremented something like:

public override void Register_client() {
    // Store callback interfaces for all connected clients:
    IMyCallback callback = OperationContext.Current.GetCallbackChannel<IGatewayServerCallback>();
    if (clients.Contains(callback) == false)
    clients.Add(callback);
    Trace.WriteLine(string.Format("Client connection established ({0})", clients.Count));
}

Where:

private List<IMyCallback> clients = new List<IMyCallback>();

The impliementation of IncrementList should do a callback to push new list (or better just the new object that was added to list) to client - something like:

for (int i = 0; i < clients.Count; i++) {
    if (((ICommunicationObject)clients[i]).State == CommunicationState.Opened) {
    try {
        clients[i].PushList(list);
    }
    catch (Exception e) {
        clients.RemoveAt(i--);
        Trace.WriteLine(e);
        Trace.WriteLine(string.Format("Removing client {0} (exception).", i + 1));
    }
}

The callback implimentation (client side) looks something like:

public class MyCallback : IMyCallback {
public void PushList(ListObject[] list) {
    // Were client side - update list code here...
}

Probably this callback implimentation needs a reference to some object that holds the list data - probably this is passed in to contructor (not shown).

When you instantiate your proxy object you will need to pass an instance of callback to the proxy constructor - something like:

MyServerClient client_proxy = new MyServerClient(new InstanceContext(my_callback, binding_str)


来源:https://stackoverflow.com/questions/7992025/wcf-client-callback-recommended

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!