【问题标题】:Is it possible to have a WCF service host not bound to any specific service type?是否可以让 WCF 服务主机不绑定到任何特定服务类型?
【发布时间】:2011-03-07 13:49:48
【问题描述】:

这篇文章与我的previous post有些关联。

简而言之,我正在尝试构建一个反向轮询 http 绑定,主机轮询其客户端的请求。我使用来自http://archive.msdn.microsoft.com/duplexhttp 的代码作为我的参考。现在,在这个绑定中,主机实际上是一个客户端,而客户端实际上是服务器。这意味着,使用此反向轮询 http 绑定的客户端必须以隐藏的服务主机结束,提供通道泵设施。

现在,使用 ServiceHost 类型的通常模式要求存在实际的 WCF 服务实现。在我的例子中,ServiceHost 在客户端是打开的——它没有服务实现,这是正确的。

我想知道解决这个问题的最佳方法是什么?

理想情况下,该服务主机不需要任何服务。轮询主机发送消息实例,这些实例未映射到任何服务合同。这些消息由专用通道请求和回复 - 分别是 HttpPollingRequestChannel 和 HttpPollingReplyChannel。但我需要它实现的通道泵设施的服务主机。

编辑 1

我想需要更多背景信息来澄清图片。我们的系统由客户端、服务器和代理组成。客户端与服务器交谈,后者将他们的请求传达给代理,代理将结果传回服务器。所有频道都是直接的 HTTP - 简单明了。

但是,需要能够在防火墙后面部署代理,而不能在其上打开入站端口。这意味着,服务器 --> 代理通信不再可能。在我看来,我有两个选择:

  1. 重新设计服务器 --> 代理协议以使其使用轮询。
  2. 实现低级别绑定,这将在内部使用轮询。

你会做出怎样的选择?虽然,第二种选择更难实现,但这是一次性的努力。但它有很多好处。可能吗?我认为是的,因为 Silverlight 和 .NET 都已经存在轮询双工 http 绑定 - 请参阅本文开头的链接。

编辑 2

我想再次强调,我不想要双工。在双工通信中,回调是在请求的上下文中执行的,这意味着代理发送请求,服务器执行回调。我的情况不同。代理什么都不发送。服务器突然决定与代理进行通信。没有代表代理的有效请求。因此,现有的双工绑定对我来说并不好,但我正在尝试从中学习如何实现轮询。

大体是这样的:

  • 代理不断轮询服务器
  • 如果服务器想要向代理发送消息,则该消息将等待下一个轮询请求,并在轮询请求回复的顶部传递给代理。

轮询请求不是任何接口的一部分,它们是在低级绑定基础架构中实现的。

【问题讨论】:

  • 如果代理在防火墙后面,它必须是发起连接的那个=它必须是服务器上托管的服务的客户端。
  • 我想尽可能地隐藏投票。当它在绑定内部时。如果没有防火墙问题,它可以让我快速重新配置代理以使用常规绑定。
  • 还是不明白。谁在您的案例中发起沟通,您的要求/限制是什么。
  • 代理向已知服务器发布自己。之后,它处于空闲状态,等待源自客户端的请求通过服务器,服务器将它们“分派”给相关代理。我特意将调度用引号括起来,因为当代理位于防火墙后面时,代理本身会轮询已知服务器以完成工作。但从逻辑上讲,联系代理的是服务器。这就是防火墙不是问题时实际发生的情况。

标签: .net wcf wcf-binding


【解决方案1】:

首先,I would not 如果我是你,请使用双工。

除了一大堆线程问题之外,如果服务器和客户端在权重和权限方面是等效的,我会使用 2 个独立的接口,一个用于服务器到客户端,另一个用于返回服务器。

如果您需要消息的完全灵活性,WCF 可能并不完全适合您。 CQRS + NServiceBus 可能更适合定义命令,并且每条消息都将强制执行需要对其执行的操作。

【讨论】:

  • 在问题正文中添加了说明。
【解决方案2】:

防火墙是双工 HTTP 不起作用的原因。考虑到这个问题出现的次数,我真希望微软永远不会创建 dualHttpBinding。

解决方案是改用 netTcpBinding 之类的东西,因为它允许通过单个连接(客户端创建的连接)进行实际的双工通信,从而解决防火墙问题。如果由于某种原因您需要使用 HTTP,则唯一的选择是让代理轮询服务。

【讨论】:

  • 如何使用 net.tcp:// ?它使用端口80吗?因为如果不是,那么由于防火墙,它根本无法工作。通常只有 80 和 443 端口是开放的,甚至有时它们也只对出站开放。
  • 我想你可以把它放在端口 80 上,如果你愿意并且服务器上没有网络服务器,但你告诉我你的服务器只打开了端口 80,你可以'不改吗?客户端不需要开放端口,它们只需要能够创建出站连接,并且大多数防火墙应该允许这样做,除非它们被设置得非常严格。
  • 我不是在谈论客户。服务器有 80 和/或 443,入站和出站 - 就是这样。没有人会让您在企业中添加更多端口。代理有 80 和/或 443 出站,有时有 80 和/或 443 入站,但有时没有。除了专用于特定业务应用程序的端口之外,其余所有端口都已关闭,不会对我们的应用程序开放,这应该能够通过 HTTP(S) 正常运行。
  • 我多么渴望过去系统管理员会问“为什么需要那个端口?”而不是盲目地打开 80 并关闭其他所有东西,无论它有多么没有意义。由于您的限制,您别无选择,只能进行轮询。 HTTP 无法按照真正的双工通信所需的方式工作。
  • 是的,这是给定的。现在的问题是如何处理它。
【解决方案3】:

在我看来,你是在浪费时间。该技术还没有为此做好准备。如果您想与客户端进行双向通信,请使用发布/订阅模式。如果您只想让服务器调用客户端,则在客户端和用户服务器上公开服务作为该服务的客户端。

为什么?

  1. 它将为您节省大量时间和预算
  2. 它会起作用 - 它已经过数以千计的现实世界解决方案的测试
  3. 如果您遇到麻烦,人们会理解并帮助您。

如果你真的需要按照你的方案放弃 WCF 并使用其他编程模型 - 可能直接使用套接字。

编辑:

好吧,如果你还想使用双工服务,我有这个想法:

  • 当代理不在防火墙后时使用WsDualHttpBinding
  • 当代理位于防火墙后面时使用PollingDualHttpBinding - 要获得此绑定,您必须安装 Silverlight 4 SDK。它位于单独的程序集 System.ServiceModel.PollingDuplex.dll 中。如果要在配置文件中使用绑定,必须将绑定注册为新的绑定扩展。

【讨论】:

  • 在问题正文中添加了说明。
  • 再次编辑了我的问题。
  • @mark:在这种情况下,您可以对 PollingDualHttpBinding 进行逆向工程,但我之前的回答仍然有效 - 我 99% 确信您在浪费时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多