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

查看:256
本文介绍了如何做一个WCF服务器通知WCF客户端的变化? (更好的解决方案,然后简单的投票,如彗星或长轮询)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

又见 WCF推送到客户端通过   防火墙

see also "WCF push to client through firewall"

我需要有一个WCF客户端连接到一个WCF服务器上,那么当一些服务器上的数据的修改的客户端需要的更新它的显示。

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.

  • 所有的通信必须通过HTTP
  • 服务器无法建立与客户的(物理)呼出。

当我写客户端和我不需要对解限只用肥皂等服务器。


我要寻找内置surport为长轮询/的Comet

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


感谢您德鲁沼泽如何在WCF执行长轮询最翔实的答案。不过,我认为主要的卖点WCF的是,你可以做这样的事情只是通过配置在配置文件中使用的信道。 例如我想要一个信道逻辑上两路,但实际收到的唯一的。

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.

推荐答案

这听起来像你对我已经知道了答案:使用长轮询。 :)所以我想留下来解释的唯一的事情就是你也许可以做到这一点与WCF并以最有效的方式。

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.

  1. 首先,决定你想要多久的每个长轮询是。为了便于讨论,我要选择5分钟超时。
  2. 在客户端的结合,改变的SendTimeout =00:05:00
  3. 就像使用XmlHtt prequest(XHR)长轮询,当超时没有实际发生,则需要检测到它,并重新发出下一个轮询请求。这是WCF很容易,因为有一个特定的异常,<一个href="http://msdn.microsoft.com/en-us/library/system.timeoutexception.aspx"><$c$c>TimeoutException,你可以捕捉到很容易检测,这是问题与一些其他异常。
  4. 根据你如何托管WCF服务,您将需要确保自己配置为允许处理长达5分钟。从纯WCF的角度来看,你会想要确保你设置 receiveTimeout =0时05分00秒。但是,如果你是ASP.NET主机里面,你还需要配置ASP.NET运行时具有更高的超时它是使用&LT进行;的httpRuntime executionTimeout =300/&GT; 注意:的测量是在几秒钟内该属性)。
  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).

如果你只是设置你的客户端同步调用服务,并在等待响应客户端块5分钟,这不是一个非常有效地利用系统资源。你可以把在后台线程这些电话,但还是会去啃一个线程资源,同时呼叫突出。最有效的方法来处理这​​个是使用异步操作。

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.

如果你手工创建的服务合同,我会建议检查出<一href="http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.asyncpattern.aspx">this在 OperationContractAttribute.AsyncPattern MSDN上一节,如何添加的BeginXXX / <$ C $细节C> EndXXX 异步方法对每个您的通话。但是,如果你使用 SvcUtil工具来为您生成你的业务合同,所有你需要做的,有产生异步方法是通过 /异步在命令行选项。有关此主题的更多详细信息,请检查出的MSDN 上的同步和异步的话题。

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.

现在,你已经走你的异步操作定义,该模式是非常喜欢用XHR工作。您调用的BeginXXX 的方法来传递哪些一个的AsyncCallback 委托。该的BeginXXX 方法将返回你的<一个href="http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx"><$c$c>IAsyncResult,你可以不放,如果你想成为能够等待的操作(在更高级的方案)或忽略,然后WCF基础结构将异步请求发送给服务器,等待幕后的响应。当接收到响应的的发生异常,你传递给的BeginXXX 方法回调会被调用。在这个回调方法,你需要调用相应的 EndXXX 方法传入的IAsyncResult 是交给你了。在调用 EndXXX 方法,你需要使用异常处理来处理,而调用方法时可能发生的任何一种逻辑错误,但这也是你在现在,d是能够赶上 TimeoutException异常我们前面谈到的。假设你有一个良好的反应,该数据将是从 EndXXX 调用返回,你能应对这些数据以任何方式很有意义。

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.

注意:有一点要记住这个模式是线程的性质。从WCF异步回调将在一个线程托管线程池。如果你打算更新UI的技术,如WPF或WinForms的,你需要确保你使用封送回调到UI线程的<一个href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke.aspx"><$c$c>Invoke或<一href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke.aspx"><$c$c>BeginInvoke的方法。

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.

如果我们要担心在客户端的效率,我们应该倍加所以当它涉及到的服务器。显然,这种类型的方法使服务器端的更多的需求,因为一个连接必须保持开放和等待状态,直到有发送通知返回给客户端的一个原因。这里的挑战是,你只需要配合WCF运行时与谁是真正被发送的事件的客户端的处理。其他的一切应该只是睡着了,等待事件发生。幸运的是,我们只是使用在客户端相同的异步模式也适用于服务器端。但是,现在有一个最大的不同:现在的的必须返回的IAsyncResult (因而<一个href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.aspx"><$c$c>WaitHandle)从的BeginXXX 方法,WCF运行时会再等待调用你的 EndXXX 方法之前,被通知的。

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.

您的没有的发现多在文档MSDN比我前面已经提供的链接等,并且里面的路很不幸,他们在写一个异步服务的样本少于有用。这就是说,<一个href="http://blogs.msdn.com/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx">Wenlong董写了一篇关于扩展WCF服务的异步模式前一段时间,我强烈建议你看看。

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.

除此之外,我老实说,我不能给对你bcause这完全取决于什么样的数据源的事件将被从第一个地方未来如何最好地实现在服务器端异步模型太多意见。文件I / O?消息队列?数据库?其他一些专有软件有自己的通讯服务,你要提供一个门面了吗?我不知道,但他们都应该提供自己的异步模式上,你可以小猪回自己的服务,使之尽可能高效。

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.

由于这似乎是一个普遍的答案,我想我应该回到这里,并提供给最近的变化的景观更新。在这一点上,现在有一个.NET库称为 SignalR 它提供了这个确切的功能,绝对是怎样,我会建议实施任何此类通信服务器

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.

这篇关于如何做一个WCF服务器通知WCF客户端的变化? (更好的解决方案,然后简单的投票,如彗星或长轮询)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆