我已经开始使用 WCF 开发客户端-服务器分布式应用程序。客户端也应该向服务器发送请求,因此我选择使用 NetTcpBinding 实现双工操作,因为所有客户端都将在同一个 Intranet 上。
在服务器端,对于实现服务器契约的服务类,我使用这些设置
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
每次初始化客户端时,我都会创建通过'Add service reference'
在 Visual Studio 中添加服务使用选项生成的代理类的实例。代理初始化后,我向Connect
服务器发送一条消息:
_proxy.InnerChannel.Faulted += new EventHandler(InnerChannel_Faulted);
_proxy.InnerChannel.Closing += new EventHandler(InnerChannel_Closing);
//send a connect message to the server
_proxy.ClientConnected(ClientHostName, Version, ClientID, ClientIP);
现在服务器有一个对连接客户端的引用,通过使用
OperationContext.Current.GetCallbackChannel<IClientEvents>()
这很简单,没什么特别的。但是,在服务器上线后让客户端重新连接到服务器时,我遇到了一些麻烦。在我的场景中,我将有多达 50-100 个客户端连接到服务器,它们很少与服务器通信,假设平均每小时 1 个请求。
我想要实现的是让客户端在离线时“挂起”,为此我尝试在每次通道结束时重新初始化客户端的通信通道Faulted
,这可以正常工作。但是当我尝试关闭服务器时,我收到以下消息
This could be because a client failed to close a sessionful channel within the required time.
我现在正在努力为我的场景找到最合适的实现:
- 服务调用后不关闭通道。这样,一旦与服务器的连接断开(例如 1 分钟的间隔),客户端将始终尝试重新创建通道。不过,一直保持频道打开没有多大意义,所以我不太确定这种方法。
- 每次调用后关闭通道并在对服务器进行新调用时重新创建。这在进行服务调用时可以正常工作,但是如果服务器想要向客户端发送通知会发生什么?服务器端的回调引用将不再有效,我必须等待客户端发送新的连接消息才能获取新的回调引用,对吗?在这种情况下,我是否应该定期对服务器进行类似于 Ping() 的不同调用,以确保服务器始终可以联系客户端?
我仍在阅读有关 WCF 双工操作的材料,只是无法确定哪种方法更好,以免以后遇到问题。
谢谢你的建议!