使用WCF实现观察者模式

3
当我首次发布这个问题时,我的Web服务和应用程序控制器之间存在强耦合,其中控制器需要打开多个线程到服务,并在收到返回数据后对返回的数据进行大量处理并将其合并为一个数据集。我不喜欢客户端需要如此多的处理和合并返回的数据才能使用,希望将该层移到服务端,并让服务打开异步线程到供应商并在返回给客户端之前合并结果。
我遇到的一个挑战是我不能等到所有线程都完成并且结果已经合并,我必须在可用数据到达时开始接收数据。这促使我在服务上实现了观察者模式,以便在新的结果集合并完成并准备好使用时通知我的应用程序,并将它们发送到应用程序。
我正在寻找如何使用ASMX Web服务或WCF来实现这一点,到目前为止我已经发现可以使用WCF来实现,但是这个主题始终开放着,欢迎提出建议和改进。

他们只有77点声望,为什么能够提供超过100的赏金? - Tim
因为 Stack Overflow(SO)会增加50点声望值,所以实际上他们会贡献50点声望值,而SO则贡献另外的50点。 - Kieron
"改进我的 Web 服务" 是一个非常泛泛的标题。如果您在问题中提到 WCF 和异步请求,可能会获得更多帮助。 - dthrasher
+1 “使用WCF实现观察者模式”是一个更好的标题! - dthrasher
6个回答

5

好的,我遇到问题的解决方案来自于WCF

除了传统的 ASMX web 服务的请求-响应操作之外,WCF 还支持其他类型的操作,如单向调用、双工回调和流式传输。

不难猜出,双工回调正是我寻找的东西。

双工回调简单地允许服务对客户端进行回调。在服务器上定义一个回调契约,并要求客户端在每次调用时提供回调终结点。然后由服务决定何时以及多少次使用回调引用。

只有双向绑定支持回调操作。WCF 提供了 WSDualHttpBinding 来支持 HTTP 上的回调(NetNamedPipeBinding 和 NetTcpBinding 也支持回调,因为 TCP 和 IPC 协议支持双向通信)。

这里需要注意的一件非常重要的事情是,双工回调是非标准的纯 Microsoft 特性。这在我的当前任务中并没有创建问题,因为我的 Web 服务和应用程序都运行在 Microsoft ASP.NET 上。

编写 WCF 服务 让我很好地开始了 WCF。它有超过 700 页,深入探讨了所有 WCF 概念,并有一个专门的章节介绍回调和其他类型的操作。

我在网上找到的一些其他好资源:

Windows Communication Foundation (WCF) 屏幕录像

MSDN 网络研讨会:从头到尾了解 Windows Communication Foundation

Web 服务软件工厂

WCF 的服务工厂


1

这似乎是采用 Windows Workflow Foundation 的一个完美案例。您可以轻松创建一个工作流程,以从每个供应商获取信息,然后在准备就绪时合并结果。这样做更加简洁,而且 WF 将为您处理所有异步操作。


1

我不确定这里是否需要双工通信...在我看来,使用标准的异步调用和回调应该足以获得数据传输的通知。

最大的问题是什么?如果你说的是异步等等,那么通常我们谈论的是将数据传输到客户端所需的时间。这是由于数据量庞大吗?还是由于在服务器上生成数据的复杂性?

如果是数据量的问题,那么我可以想到许多显著提高性能的方法 - 尽管其中大部分涉及使用 DTO 对象(而不是问题中暗示的 DataSet/DataTable)。例如,protobuf-net 可以显著减少传输数据所需的数据量和处理。


0

实现这一点的方法之一是通过异步调用您的WS(http://www.stardeveloper.com/articles/display.html?article=2001121901&page=1, http://www.ondotnet.com/pub/a/dotnet/2005/08/01/async_webservices.html),然后在回调中更新GUI。

但是,如果数据查询时间过长,您可能会遇到超时问题。例如,如果供应商的网站之一崩溃或非常缓慢,这可能意味着整个查询都会失败。也许更好的方法是在客户端的业务逻辑中进行合并,而不是由WS来执行。


0

不确定这个解决方案是否适用于您的特定任务,但无论如何:

  1. 将分页参数添加到您的WS API中(int pageNumber、int pageSize、out int totalPages)
  2. 添加一个短暂的TTL缓存,将请求细节(可能是哈希值)与输出数据关联起来

当您的应用程序请求第一页时,尽快返回它,并将收集/合并的所有数据整体放入缓存,因此当需要下一页时,您可以使用已经准备好的数据。

但请注意,您将无法获取最新的数据,请谨慎配置缓存重新加载间隔。


谢谢,我可以用与我在初始帖子中提到的类似的方式处理这个问题,即进行多个请求并接收准备好的内容。我希望有更少“臭味相投”的方法来完成这个任务,特别是使用WCF。我想我需要深入了解WCF并看看能得出什么结果。 - kaivalya

0
在您的情况和技术中,归档的绝佳方式是在您的 Web 应用程序/库与您的 Web 服务之间设置某种令牌,并且您的控制器需要有一个线程来检查是否有新结果等。但请注意,您需要从 WS 中获取完整的数据,因为合并可能会导致初始响应中删除项目。
或者我仍然认为使用 WCF Web 服务从控制器处理线程会更好。

这基本上是我目前提出的方法.. 我不喜欢通过线程不断向WS询问其它信息的做法。正在寻找更好的模式。希望能尽快进行一些研究,并发布我的成果.. - kaivalya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接