本文介绍了WCF - 建议客户端回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF服务公开了两个操作 - IncrementList()和GetList()。客户端B连接到服务,调用GetList()并显示给用户。客户端A能够通过调用IncrementList()来更新此列表。

我希望客户端B在调用IncrementList()时得到通知,因此可以再次调用GetList()来显示更新的数据。 p>
请你介绍一下如何实现这一点? CallBacks?双工?发布商/订阅者?


在WCF 4.0中有什么新的东西有助于这个场景?




谢谢!

解决方案

你应该决定前面是,如果你想推整个列表,当增量(重)或只是更新的项目到每个客户端。下面的代码是推整个列表,但容易修改这只是推动更新的对象(推荐)。

在应用程序启动客户端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] ...
}



您的客户应该提供:

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

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

  public override void Register_client(){
//存储所有连接客户端的回调接口:
IMyCallback callback = OperationContext.Current.GetCallbackChannel< IGatewayServerCallback>();
if(clients.Contains(callback)== false)
clients.Add(callback);
Trace.WriteLine(string.Format(Client connection established({0}),clients.Count));
}

其中:

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

插入 IncrementList 推送新的列表(或更好只是添加到列表中的新对象)到客户端 - 类似:

  for i = 0; 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(删除客户端{0}(异常)。,i + 1));
}
}

回调实现(客户端)

  public class MyCallback:IMyCallback {
public void PushList(ListObject [] list){
//这里是客户端更新列表代码...
}

这个回调需要



当你实例化你的代理对象时,你需要传递一个代理构造函数的回调实例 - 类似:

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


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!

解决方案

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)

这篇关于WCF - 建议客户端回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 22:26