2

假设您已经创建了一个双工服务——例如使用 NetTcpBinding——并且它被配置为作为发布-订阅模式为新客户端的每个新订阅创建一个新会话:每次新客户端连接时,都会创建一个新服务实例. 如果客户端想要断开连接,它调用的Unsubscribe()方法足以结束其会话。

还假设服务有一个方法来验证客户端是否处于活动状态——也就是说,客户端必须定期调用此方法:如果服务检测到客户端不再处于活动状态,则服务决定与客户端断开连接是有意义的。客户。类似地,如果用户决定关闭托管它的应用程序,服务可能会决定终止所有会话。

  • 如何从服务端终止会话?
  • 客户端(即自动生成的代理)如何检测到服务想要断开连接或正在断开连接?它会抛出异常吗?

更新

我阅读了有关ICommunicationObject接口、CommunicationObject类、IDisposable接口等的信息,所以我尝试使用ICommunicationObject与回调相关的一个:

ICommunicationObject obj = (ICommunicationObject)callback;
obj.Close();

这样,会话实例被干净地销毁(Dispose()调用该方法后调用析构函数Close()),如果客户端尝试发送请求,则ProtocolException在其上启动:

此通道不能再用于发送消息,因为输出会话由于服务器启动的关闭而自动关闭。通过将 DispatchRuntime.AutomaticInputSessionShutdown 设置为 false 来禁用自动关闭,或者考虑使用远程服务器修改关闭协议。

同样,使用上面的代码但调用Abort()方法,服务实例被销毁,并且CommunicationObjectFaultedException在客户端抛出异常:

通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信,因为它处于故障状态。

我得到的行为几乎是我想要的,但我不确定这是否是正确的方法。

4

1 回答 1

2

如果您想因不活动而关闭会话,您最好利用可靠的会话不活动超时http://msdn.microsoft.com/en-us/library/system.servicemodel.reliablesession.inactivitytimeout.aspx,这里的基础设施将自动关闭为你开会。否则,对于手动方法,您可以尝试 OperationContext.Current.InstanceContext.Close() 或 OperationContext.Current.InstanceContext.Abort()

于 2012-06-27T18:11:22.590 回答