1

使用提示的技术:

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.callbackcontract.aspx

我正在为我的 API 实现一个 ServerPush 设置,以从事件服务器(无轮询)获取实时通知。基本上,服务器有一个 RegisterMe() 和 UnregisterMe() 方法,客户端有一个称为 Announcement(string message) 的回调方法,通过 WCF 中的 CallbackContract 机制,服务器可以调用。这似乎运作良好。

不幸的是,在此设置中,如果服务器崩溃或不可用,客户端将不知道,因为它只是在侦听消息。在线沉默可能意味着没有公告,或者可能意味着服务器不可用。

由于我的目标是减少轮询而不是即时性,因此我不介意在服务器上添加一个 void Ping() 方法以及 RegisterMe() 和 UnregisterMe() ,该方法仅用于测试与服务器的连接性。我相信,定期测试这种方法可以确保我们仍然保持连接(并且传输没有丢弃任何公告,因为这是 TCP)

但是 Ping() 方法是必需的还是默认情况下作为 WCF 的一部分提供的连接测试 - 例如 serverProxy.IsStillConnected() 或其他东西。据我了解,通道的状态只会在失败的 Ping() 之后返回故障或关闭,而不是代替它。

2)从更广泛的角度来看,这种回调方法是否可靠?这不适用于 http 或 ajax - 连接的客户端数量将很少(数十个客户端,最大)。这种方法是否存在严重问题?由于这似乎是一个轻微的风险,我如何通过不足够快地处理它的回调队列来限制慢速/恶意客户端阻塞服务器?是否有一种特定于回调的超时,我可以设置而不影响其他操作?

4

3 回答 3

2

您的方法听起来很合理,这里有一些可能有帮助也可能没有帮助的链接(它们并不完全相关):

在 WCF 双工合同中检测客户端死亡 http://tomasz.janczuk.org/2009/08/performance-of-http-polling-duplex.html

在您的应用程序协议中内置一些健康检查是有意义的。

如果您担心恶意客户端,请添加授权。

我在上面分享的第二个链接有一个示例发布/订阅服务器,您也许可以使用此代码。需要注意的几件事——考虑通过异步调用或在单独的线程上推送通知。并在 tcp 绑定上设置 sendTimeout。

高温高压

于 2009-11-07T05:02:52.767 回答
1

我写了一个 WCF 应用程序,遇到了类似的问题。我的服务器通过定期向客户端发送 ping 来检查客户端没有“拔掉插头”。实际的发送方法(作为服务器是异步的)有 30 秒的超时。客户端每隔 30 秒检查一次是否接收到数据,而如果达到超时,服务器将捕获异常。

连接到服务器需要授权(通过使用 WCF 的内置功能强制连接人员首先调用特定方法),因此从恶意客户端的角度来看,您可以轻松添加代码来检查并禁止他们的帐户,如果他们这样做一些可疑的东西,同时断开未进行身份验证的用户。

由于我编写的服务器是异步的,因此没有任何方法可以真正阻止它。我想这解决了您的最后一点,因为异步发送方法会触发 ping(以及任何其他数据发送)并立即返回。在 SendEnd 方法中,它会捕获超时异常(有时对于客户端来说是多个)并断开它们,而不会阻塞或冻结服务器。

希望有帮助。

于 2009-11-10T12:10:34.577 回答
1

您可以使用类似于 Juval 建议的发布者/订阅者服务:http: //msdn.microsoft.com/en-us/magazine/cc163537.aspx

如果丢失服务器是典型情况,这将允许您保留订阅者。本例中的 publish 方法也在单独的线程上调用每个订阅者,因此一些死订阅者不会阻塞其他订阅者...

于 2009-11-11T18:18:42.183 回答