WCF - 推荐客户端回调?

Gus*_*nti 2 wcf callback wcf-callbacks

我有一个WCF服务,它公开两个操作 - IncrementList()和GetList().客户端B连接到服务,调用GetList()并显示给用户.客户端A能够通过调用IncrementList()来更新此列表.
我希望客户端B在调用IncrementList()时得到通知,这样它可以再次调用GetList()来显示更新的数据.

您能否概述一下如何实现这一点?回调?复式?发布/订阅?
WCF 4.0中有哪些新功能可以帮助实现这种情况?

服务图

谢谢!

Ric*_*bob 5

您应该事先决定的是,如果您希望在每个客户端增加(重)或仅更新项目时推送整个列表.下面的代码用于推送整个列表,但很容易修改它只是为了推送更新的对象(推荐).
在应用程序启动时,客户端B应该调用Register_client然后GetList.随后,当列表递增时,将通过回叫通知它(客户端需要支持此接口)
该呼叫GetList需要双工通道和SessionMode.Required.

你的服务器应该恭维:

[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]...
}
Run Code Online (Sandbox Code Playgroud)

您的客户应该恭维:

public interface IMyCallback {
    [OperationContract(IsOneWay = true)]
    void PushList(ListObject[] list);
}
Run Code Online (Sandbox Code Playgroud)

注册客户端只需要存储客户端回调接口,以便在列表增加时使用:

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));
}
Run Code Online (Sandbox Code Playgroud)

哪里:

private List<IMyCallback> clients = new List<IMyCallback>();
Run Code Online (Sandbox Code Playgroud)

的impliementation IncrementList应该做一个回调来推动新的列表(或更好的只是加入到列出新的对象)的客户-是这样的:

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

回调实现(客户端)看起来像:

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

可能这个回调实现需要引用一些保存列表数据的对象 - 可能这会传递给构造函数(未显示).

实例化代理对象时,需要将回调实例传递给代理构造函数 - 类似于:

MyServerClient client_proxy = new MyServerClient(new InstanceContext(my_callback, binding_str)
Run Code Online (Sandbox Code Playgroud)