WCF服务器如何通知WCF客户端的变化?(比简单的轮询更好的解决方案,例如Comet或长轮询)[英] How does a WCF server inform a WCF client about changes? (Better solution then simple polling, e.g. Comet or long polling)

本文是小编为大家收集整理的关于WCF服务器如何通知WCF客户端的变化?(比简单的轮询更好的解决方案,例如Comet或长轮询)的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

另请参见" wcf通过 防火墙"

我需要拥有一个连接到WCF服务器的WCF客户端,然后当服务器上的某些数据更改时,客户端需要更新它的显示./p>

由于客户端和服务器之间可能会有防火墙.

  • 所有通信必须超过http
  • 服务器无法(物理)向客户端打电话.

当我编写客户端和服务器时,我不需要将解决方案限制为仅使用SOAP等.


我正在寻找" 长民意调查"/=" http://en.wikipedia.org/wiki/comet_(编程)"


感谢Drew Marsh关于如何在WCF中实施长期民意调查的最有用的答案.但是,我认为WCF的主要"卖点"是您只需配置要在配置文件中使用的通道即可完成此类操作. 例如,我想要一个逻辑上两种方式但仅在物理上传入的通道.

推荐答案

在我看来,您已经知道答案了:使用长期投票. :)所以我想唯一要解释的是您如何以WCF和最有效的方式完成此操作.


基础知识:

  1. 首先,确定您想要每次"长民意调查"的时间.为了论证,我将选择5分钟的超时.
  2. 在客户端绑定上,更改sendTimeout="00:05:00".
  3. 就像使用XMLHTTPRequest(XHR)进行长时间的轮询一样,当超时确实发生时,您将需要检测并重新发出下一个投票请求.在WCF中,这很容易,因为有一个特定的例外, TimeoutException TimeoutException TimeoutException ,您可以轻松地发现这是问题与其他一些例外.
  4. 根据您如何托管WCF服务,您将需要确保配置自己以允许多达5分钟的处理.从纯WCF的角度来看,您需要确保设置receiveTimeout="00:05:00".但是,如果您在ASP.NET内部托管,则还需要配置ASP.NET运行时以具有较高的超时,该超时使用<httpRuntime executionTimeout="300" />(注:测量此属性的秒).

在客户端效率

如果您只是设置客户端在等待响应时同步调用服务和5分钟的客户块,那么这不是非常有效的系统资源使用.您可以将这些呼叫放在背景线程上,但是在呼叫很出色时,这仍然会咀嚼线程资源.处理此问题的最有效方法是使用异步操作.

如果您要手工创建服务合同,我建议您检查 OperationContractAttribute.AsyncPattern 上的MSDN上的本节,有关如何为每个呼叫添加BeginXXX/EndXXX async方法对的详细信息.但是,如果您使用svcutil为您生成操作合同,那么生成异步方法的所有要做的就是通过命令行上的/async选项.有关此主题的更多详细信息,请查看MSDN .

既然您已经进行了异步操作定义,那么该模式就像使用XHR一样.您可以调用BeginXXX通过 a AsyncCallback a AsyncCallback demegate . BeginXXX方法将返回您 IAsyncResult ,如果您想能够等待操作(在更高级的方案)或忽略操作,则可以坚持下去,然后WCF基础架构将异步将请求发送到服务器并等待幕后的响应.当收到响应或发生异常时,将调用您输入BeginXXX方法的回调.在此回调方法内部,您需要调用传递给您的IAsyncResult中的相应EndXXX方法.在调用EndXXX方法期间,您需要使用异常处理来处理调用该方法时可能发生的任何逻辑错误,但这也是您现在可以捕获TimeoutException的地方早些时候谈论.假设您得到了良好的响应,数据将是从EndXXX调用中返回的数据,您可以以任何方式对该数据做出反应.

注意:要记住这种模式的一件事是螺纹的本质. WCF的异步回调将在线程上从 >.如果您打算在WPF或Winforms等技术中更新UI,则需要确保使用 Invoke BeginInvoke 方法.

在服务器上有效

如果我们要担心客户端的效率,那么我们应该双重地涉及服务器.显然,这种类型的方法在服务器端增加了需求,因为连接必须保持打开状态和待处理,直到有理由将通知发送给客户端为止.这里的挑战是,您只想将WCF运行时与实际发送活动的客户的处理联系起来.其他一切都应该睡着,等待事件发生.幸运的是,我们刚刚在客户端使用的同样异步模式也可以在服务器端工作.但是,现在有一个主要区别:现在 you 必须返回IAsyncResult(因此, WaitHandle )来自BeginXXX方法,然后WCF运行时将等待在调用您的EndXXX方法之前先等待发出信号.

.

您将 除了我之前已经提供的链接外,在MSDN内部的文档中找到了很多东西,不幸的是,他们编写异步服务的样本却不有用.也就是说,温隆东(Wenlong Dong)写了一篇有关使用异步模型扩展WCF服务的文章我强烈建议您退房.

除此之外,老实说,我不能为如何最好地在服务器端实现异步模型的建议太多,这完全取决于您的事件将首先来自哪种数据源.文件I/O?消息队列?数据库?您正在尝试提供立面的其他一些专有软件以及自己的消息传递服务?我不知道,但是他们都应该提供自己的异步模型,您可以在其上可以恢复自己的服务以使其尽可能高效.

更新处方

由于这似乎是一个受欢迎的答案,所以我认为我应该回到这里,并在景观中的最新变化后回到这里提供更新.此时,现在有一个.NET库,称为 signalr ,它提供了这种确切的功能,并且绝对是我推荐的方式与服务器实施任何此类通信.

其他推荐答案

如果服务器可以与服务总线进行传出连接,则可以诱发回电的类型.这样,客户端/服务器根本不需要彼此了解,只有依赖服务总线.请参阅 .net服务总线

您将需要研究 wsdualhttpbind

wsdualhttpbinding提供了 对Web服务协议的支持相同 作为wshtpbinding,但可用于 双工合同. wsdualhttpbinding 仅支持肥皂安全性和 需要可靠的消息传递.这个 绑定要求客户有一个 提供回调的公共UI 服务的端点.这是 由Clientbaseaddress提供.一个 双重绑定公开了IP地址 服务客户.客户端 应该使用安全性确保 仅连接到它信任的服务.

其他推荐答案

虽然不是WCF,您可以尝试使用XMPP来使该功能运行.在 infoq 关于它和其他系统的文章上.虽然该文章指出XMPP不能通过http使用,但您可以在使用 bosh .

有.net库可用 agsxmpp p>

我工作的公司开始使用它将更新通知推向应用程序以刷新用户界面的部分.

本文地址:https://www.itbaoku.cn/post/627607.html

问题描述

see also "WCF push to client through firewall"

I need to have a WCF client that connect to a WCF server, then when some of the data changes on the server the clients need to update its display.

As there is likely to be a firewall between the clients and the server.

  • All communications must be over HTTP
  • The server can not make an (physical) outgoing call to the client.

As I am writing both the client and the server I do not need to limit the solution to only using soap etc.


I am looking for built in surport for "long polling" / "Comet" etc


Thanks for the most informative answer from Drew Marsh on how to implement long polling in WCF. However I thought the main “selling point” of WCF was that you could do this sort of thing just by configuring the channels to be used in the config file. E.g I want a channel that logically two way but physically incoming only.

推荐答案

It sounds to me like you already know the answer: use long polling. :) So I guess the only thing left to explain is how you might be able to accomplish this with WCF and in the most efficient manner possible.


The basics:

  1. First, decide how long you want each "long poll" to be. For argument's sake I'm going to choose 5min timeouts.
  2. On the client side binding, change the sendTimeout="00:05:00".
  3. Just like using XmlHttpRequest (XHR) for long polling, when the timeout does actually occur, you will need to detect it and re-issue the next polling request. This is quite easy in WCF because there is a specific exception, TimeoutException, that you can catch to easily detect this was the issue vs. some other exception.
  4. Depending on how you're hosting your WCF service, you will need to make sure to configure yourself to allow processing for up to 5mins. From a pure WCF perspective you'll want to make sure you set the receiveTimeout="00:05:00". However, if you're hosting inside of ASP.NET you will also need to configure the ASP.NET runtime to have a higher timeout which is done using the <httpRuntime executionTimeout="300" /> (note: the measurements are in seconds for this attribute).

Being efficient in the client

If you just setup your client to synchronously call the service and the client blocks for 5mins while waiting for a response, that's not a very efficient use of system resources. You could put these calls on background threads, but that's still going to chew up a thread resource while the call is outstanding. The most efficient way to deal with this is to use async operations.

If you're creating your service contracts by hand, I would suggest checking out this section on MSDN on OperationContractAttribute.AsyncPattern for details on how to add a BeginXXX/EndXXX async method pair for each of your calls. However, if you're using svcutil to generate your operation contracts for you, all you need to do to have async methods generated is pass the /async option on the command line. For more details on this topic, check out the Synchronous and Asynchronous topic on MSDN.

Now that you've go your async operations define, the pattern is very much like working with XHR. You call the BeginXXX method to which you pass an AsyncCallback delegate. The BeginXXX method will return you an IAsyncResult, which you can either hold onto if you wanted to be able to wait on the operation (in more advanced scenarios) or ignore, and then the WCF infrastructure will asynchronously send the request to the server and wait for a response behind the scenes. When a response is received or an exception occurs, the callback you passed into the BeginXXX method will be invoked. Inside of this callback method you need to call the corresponding EndXXX method passing in the IAsyncResult that is handed to you. During the call to the EndXXX method you need to employ exception handling to deal with any kind of logical fault that may have occurred while calling the method, but this is also where you'd now be able to catch the TimeoutException we talked about earlier. Assuming you got a good response, the data will be the returned from the EndXXX call and you can react to that data in whatever way makes sense.

NOTE: One thing to keep in mind about this pattern is the nature of the threading. The async callbacks from WCF will be received on a thread from the managed thread pool. If you're planning on updating the UI in a technology such as WPF or WinForms, you need to make sure you marshal the calls back to the UI thread using the Invoke or BeginInvoke methods.

Being efficient on the server

If we're going to be worried about efficiency in the client, we should be doubly so when it comes to the server. Obviously this type of approach puts more demand on the server side because a connection must remain open and pending until there is a reason to send notification back to the client. The challenge here is that you only want to tie the WCF runtime up with the processing of those clients who are actually being sent an event. Everything else should just be asleep, waiting for the event to occur. Luckily the same async pattern we just used on the client side also works on the servers side. However, there is now a major difference: now you must return the IAsyncResult (and thus a WaitHandle) from the BeginXXX method which the WCF runtime will then wait to be signaled on before calling your EndXXX method.

You will not find much in the way of documentation inside of MSDN other than the links I've already provided earlier and, unfortunately, their samples on writing an async-service are less than useful. That said, Wenlong Dong wrote a piece about scaling WCF services with the async model some time ago that I highly recommend you check out.

Beyond this, I honestly I can't give too much advice on how best to implement the asynchronous model on the server side for you bcause it depends entirely on what kind of data source your events will be coming from in the first place. File I/O? A message queue? A database? Some other proprietary software with its own messaging service that you're trying to provide a façade over? I don't know, but they should all offer an async models of their own on which you can piggy back your own service to make it as efficient as possible.

Updated Prescription

Since this seems to be a popular answer, I figured I should come back here and provide an update given the recent changes in the landscape. At this point there is now a .NET library called SignalR which provides this exact functionality and is definitely how I would recommend implementing any such communication with the server.

其他推荐答案

If the server could make an outgoing connection to a service bus you could implament a type of call back. This way the client/server would not need to know about each other at all, just the relying service bus. See .NET Service Bus

You will want to look into WSDualHttpBinding

The WSDualHttpBinding provides the same support for Web Service protocols as the WSHttpBinding, but for use with duplex contracts. WSDualHttpBinding only supports SOAP security and requires reliable messaging. This binding requires that the client has a public URI that provides a callback endpoint for the service. This is provided by the ClientBaseAddress. A dual binding exposes the IP address of the client to the service. The client should use security to ensure that it only connects to services it trusts.

其他推荐答案

While not WCF you could try to use XMPP to get that functionality going. There's an article on InfoQ about it and other systems. While the article states that XMPP can't be used over HTTP, you can when using BOSH.

There are .NET libraries available agsXMPP to name one.

The company where I work is starting to use it to push update notifications to an application for it to refresh parts of the user interface.