我觉得你已经知道答案了:使用长轮询。 :) 所以我想唯一需要解释的是如何使用 WCF 并以最有效的方式实现这一点。
sendTimeout="00:05:00"
。TimeoutException
,您可以捕获以轻松检测这是问题还是其他异常。receiveTimeout="00:05:00"
。但是,如果您在ASP.NET中托管,则还需要配置ASP.NET运行时具有更高的超时时间,这可以使用<httpRuntime executionTimeout="300" />
来完成(注意:此属性的测量单位为秒)。如果您只是设置客户端同步调用服务,并且客户端在等待响应时阻塞了5分钟,那么这不是系统资源的有效使用。您可以将这些调用放在后台线程中,但这仍然会在调用未完成时消耗线程资源。处理此问题的最有效方法是使用异步操作。
如果你手动创建服务契约,我建议查看MSDN上关于OperationContractAttribute.AsyncPattern
的这一部分以获取有关如何为每个调用添加BeginXXX
/EndXXX
异步方法对的详细信息。但是,如果你使用svcutil
为你生成操作契约,你只需要在命令行上传递/async
选项即可生成异步方法。有关此主题的更多详细信息,请查看MSDN上的同步和异步主题。BeginXXX
方法,并传递一个AsyncCallback
委托。 BeginXXX
方法将返回IAsyncResult
,如果需要等待操作(在更高级的场景中),则可以将其保留,或者忽略,然后WCF基础结构将在后台异步发送请求到服务器并等待响应。当收到响应或发生异常时,将调用传递给BeginXXX
方法的回调。在此回调方法内,您需要调用相应的EndXXX
方法,将交给您的IAsyncResult
传递进去。在调用EndXXX
方法期间,您需要使用异常处理来处理可能发生的任何逻辑故障,但这也是您现在能够捕获我们之前提到的TimeoutException
的地方。假设您得到了一个良好的响应,则数据将从EndXXX
调用中返回,您可以以任何合理的方式对该数据做出反应。
注意: 关于这个模式,需要记住的一件事是线程的性质。来自WCF的异步回调将在托管线程池中的一个线程上接收。如果你计划在诸如WPF或WinForms等技术中更新UI,则需要确保使用Invoke
或BeginInvoke
方法将调用传回UI线程。
WaitHandle
),WCF运行时将在调用EndXXX方法之前等待被触发。由于这似乎是一个受欢迎的答案,我认为我应该回来并提供一个更新,考虑到最近的变化。目前有一个名为SignalR的.NET库,提供了这种精确功能,绝对是我推荐实现与服务器通信的方式。
谷歌搜索“WCF双工”(Programming相关)。 我已经在不同大陆成功地使用了netTcpBinding来实现这个,但我不确定basicHttpBinding是否适用。
不过,这确实需要服务器回调客户端。如果服务器不允许这样做,则轮询可能是您唯一的选择...
如果服务器不能调用客户端(通常情况下不应该),您应该像您指定的那样让客户端轮询服务器。 由于您已经有了 WCF 基础,只需添加一个相应的操作即可。