WCF-建议客户端回调?

WCF-建议客户端回调?,wcf,callback,wcf-callbacks,Wcf,Callback,Wcf Callbacks,我有一个WCF服务,它公开了两个操作—IncrementList和GetList。客户端B连接到服务,调用GetList并向用户显示。客户端A可以通过调用IncrementList来更新此列表。 我希望客户端B在调用IncrementList时得到通知,以便它可以再次调用GetList以显示更新的数据。 你能概述一下你将如何实施这一点吗?回电?双工?发布者/订阅者? WCF 4.0中有什么新功能可以帮助解决此问题吗? 谢谢 您应该提前决定的是,当列表递增时,是要将整个列表推送到每个客户机,还是

我有一个WCF服务,它公开了两个操作—IncrementList和GetList。客户端B连接到服务,调用GetList并向用户显示。客户端A可以通过调用IncrementList来更新此列表。 我希望客户端B在调用IncrementList时得到通知,以便它可以再次调用GetList以显示更新的数据。 你能概述一下你将如何实施这一点吗?回电?双工?发布者/订阅者? WCF 4.0中有什么新功能可以帮助解决此问题吗?


谢谢

您应该提前决定的是,当列表递增时,是要将整个列表推送到每个客户机,还是只将更新的项目推送到每个客户机。下面的代码用于推送整个列表,但很容易修改,只需推送推荐的更新对象即可。 在应用程序启动时,客户端B应调用Register_客户端,然后调用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]...
}
public interface IMyCallback {
    [OperationContract(IsOneWay = true)]
    void PushList(ListObject[] list);
}
您的客户应实施:

[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]...
}
public interface IMyCallback {
    [OperationContract(IsOneWay = true)]
    void PushList(ListObject[] list);
}
注册客户端只需要存储客户端回调接口,以便在列表递增时使用,如:

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));
}
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));
    }
}
public class MyCallback : IMyCallback {
public void PushList(ListObject[] list) {
    // Were client side - update list code here...
}
回调实现客户端类似于:

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));
}
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));
    }
}
public class MyCallback : IMyCallback {
public void PushList(ListObject[] list) {
    // Were client side - update list code here...
}
可能这个回调实现需要对保存列表数据的某个对象的引用-可能这是传递给constructor的,但没有显示

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

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

你期望的工作量是多少?是否有任何代理/防火墙等?通知需要多快?问题是什么?您当前问题的答案是肯定的,因为只有使用回调的双工绑定才能实现通知,而双工绑定是发布/订阅消息交换模式的核心。WCF 4中没有更多内容支持这一点。Yahia,没有代理或防火墙,通知也不需要实时。Ladislav Mrnka,对不起-我意识到我的问题很模糊,很明显我对WCF非常熟悉。。。我的问题是你真的会如何实现这一点?Bob,非常感谢你给出如此完整的答案!我显然是WCF的新手,我有一个问题:我在想我可以简单地从服务中公开一个事件,然后客户端就会订阅它。然后,事件的处理程序将调用GetList。这可能吗?我不是要求为我写代码,但你能概述一下步骤吗谢谢你@GustavoCavalcanti我本人对WCF相当了解,但有一个或多或少基于以上内容的应用程序运行良好。我的理解是,不能直接在服务器接口上公开事件。相反,我在这里要做的是在回调接口上公开一个与事件具有类似签名的方法,然后在客户端实现该方法时触发事件——只需传递参数。我们的UI应用程序可以处理接口上的事件-但是我们可以插入接口正常事件的本地实现或使用方法->事件的远程wcf代理实现。感谢Ricibob的澄清。Ricibob,请显示PushList的代码好吗?谢谢