识别 WCF 服务中的客户端

识别 WCF 服务中的客户端

问题描述:

我有一个带有 WSDualHttpBinding 的双工 WCF 服务.我的问题是想出一种方法来存储具有唯一 ID 的回调通道.该服务旨在长期运行.我可以在调用订阅"方法时简单地获取 OperationContext.Current.GetCallbackChannel() 返回值并将其存储在列表或字典中吗?是否保证在连接有效之前一直有效?

I have a working duplex WCF service with WSDualHttpBinding. My problem is figuring out a way to store the callback channel with a unique id. The service is intended to be long-running. Can I simply grab the OperationContext.Current.GetCallbackChannel() return value when a "Subscribe" method is called and store it in a list or dictionary? Is it guaranteed to be valid until the connection is alive?

最简单的方法是让客户端在您的服务的 Subscribe 方法中提交一个键值.然后,您可以将回调通道保存在字典中.这个字典可能需要是一个静态变量或单例类,其生命周期大于服务类的生命周期,因为大多数服务类都有一个 PerCall 生命周期,并在服务调用完成后被处理掉.注意线程问题!

The easiest way would be to have the client submit a key value in the Subscribe method of your service. You could then save the Callback channel in a dictionary. This dictionary would probably need to be a static variable or singleton class whose lifespan is greater than the Service Class's lifespan since most service class's have a PerCall lifetime and get disposed of after the service call is complete. Beware of threading issues!

回调通道随时可能出现故障,无论是客户端还是服务端.该服务必须处理故障通道的可能性,并从字典中删除故障通道.WSDuallHttpBinding 是一种无状态"绑定,因此在服务端尝试调用它们之前,不会在服务端检测到客户端中的任何故障.如果客户端进入故障状态,NetTcpBinding 将引发 ChannelFaulted 事件.因此,如果 NetTcpBinding 符合您的要求,我会推荐它.

The callback channel can be faulted at any time either on the client or the service side. The service has to handle the possibility of a faulted channel and to remove the faulted channel from the dictionary. WSDuallHttpBinding is a "Stateless" binding so any faults in the client won't be detected on the service side until the service side attempts to call them. NetTcpBinding will raise the ChannelFaulted event if the client gets into a faulted state. For that reason I would recommend the NetTcpBinding if it fits your requirements.

public bool Subscribe(string id) {
        ICallback callback = OperationContext.Current.GetCallbackChannel();
        if (!_activeCallbackChannels.Contains(id)) {
            _activeCallbackChannels.Add(id, callback);
            return true;
        }
        else {
            return false;
        }

    }