我正在开发一个使用 WCF 在服务器和客户端之间进行通信的应用程序 服务器具有不断变化的服务数量,以及一项主服务,客户端可以查询有关其他服务的信息,然后使用主服务中的信息订阅他们想要的服务。
当子服务发生更改(添加、删除等)时,主服务会向订阅的客户端发送通知 此外,子服务每隔几秒就会发送一次通知。
这听起来像是使用 WCF 回调 channel 的绝佳机会,但是,它们要求您使用 session 。此外,当向客户端发送通知时,当任何客户端不光彩地断开连接时,服务会挂起,并尝试通知它。即使超时,在一段时间后,在此期间没有其他客户端收到通知,这是 Not Acceptable ,因为客户端实际上是用于监控子服务后面的应用程序的 GUI。 同样,使用 MSMQ 也不是一种选择,因为服务需要立即知道发送操作何时未成功。
我想出的解决方案是使用 http 绑定(bind)(在发送失败时立即知道)并在客户端上创建显式回调服务,但这需要我编写大量看起来丑陋的基础设施代码。
所以,我的问题是:是否有更好的方法使用 WCF 来做到这一点。最好看的选项是回调合约,因为这使我无需手动管理回调服务,只要它在尝试发送到下一个客户端之前无法等待一个客户端的确认即可。
最佳答案
我有一个类似的环境(没有动态服务),并且当客户端 channel 出现故障时遇到了非常类似的问题。我想出的第一个解决方案是将回调包装在 try/catch 语句中,并在出现问题时删除有问题的客户端,但这有问题,而且看起来根本无法扩展。
我最终采用的解决方案是使用委托(delegate)事件处理程序并使用 BeginInvoke 调用它。如果您还没有看过CodeProject: WCF/WPF Chat Application (Chatters)解决方案,我建议您检查一下。
当用户登录时,将创建一个事件处理程序并将其添加到主事件中:
public bool Login()
{
...
_myEventHandler = new ChatEventHandler(MyEventHandler);
ChatEvent += _myEventHandler;
...
}
每当需要广播消息时,就会异步调用事件处理程序:
private void BroadcastMessage(ChatEventArgs e)
{
ChatEventHandler temp = ChatEvent;
if (temp != null)
{
foreach (ChatEventHandler handler in temp.GetInvocationList())
{
handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
}
}
}
当返回返回时,结果将被处理,如果发生错误,该 channel 的事件处理程序将被删除:
private void EndAsync(IAsyncResult ar)
{
ChatEventHandler d = null;
try
{
//get the standard System.Runtime.Remoting.Messaging.AsyncResult,and then
//cast it to the correct delegate type, and do an end invoke
System.Runtime.Remoting.Messaging.AsyncResult asres = (System.Runtime.Remoting.Messaging.AsyncResult)ar;
d = ((ChatEventHandler)asres.AsyncDelegate);
d.EndInvoke(ar);
}
catch(Exception ex)
{
ChatEvent -= d;
}
}
上面的代码是从 Sacha Barber 发布的 WCF/WPF 聊天应用程序(稍作修改)修改而来的。 .
关于wcf - 如何: Responsive available Wcf duplex communication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/340085/