何时使用双工服务?

Posted

技术标签:

【中文标题】何时使用双工服务?【英文标题】:when to use duplex service? 【发布时间】:2012-06-26 21:48:15 【问题描述】:

嗯,我知道在双工合同中,服务可以向客户端发送消息,但我想知道什么时候这才真正有用。

我有一个常见的应用程序,它向服务发送请求以从数据库中获取数据、插入数据......等等。另外,我需要在数据库中存储大约 40MB 的文件,所以我需要一个良好的性能。出于这个原因,我想使用传输模式流式传输的net.tcp绑定,但问题是net.tcp双工服务无法使用流式传输模式。

所以我想我有一些选择。

1.- 研究我是否真的需要这种应用程序的双工合同。例如,也许在聊天应用程序中,双工合同更有意义,因为服务器可能需要在联系人连接时通知客户端......等等。但在普通客户端中,访问数据库是必要的双重合同?什么样的操作需要双工合同?

2.- 其他选项是不具有双工合同,而是在服务器中实现无双工合同,在客户端中实现其他单合同,因此当客户端连接到服务时,服务会收到所需的信息以连接到客户端的服务。但是,这是避免双重合同的好方法吗?

3.- 对于我的应用程序,我真的需要 tcp 而不是允许流传输模式的双工 HTTP 吗? tcp 在性能方面比 HTTP 有什么优势?

谢谢。

【问题讨论】:

【参考方案1】:

如果你想实现回调模式,你需要双工。回调意味着客户端不知道服务器何时发生某些事件。

如果您不知道事件何时发生,您有两种选择:

    轮询 - 每 X 分钟发送一次请求以检查事件是否发生。服务器应返回事件详细信息(如果发生)或返回标志,表明您需要继续调用。服务器还可以在高级场景中返回建议的超时时间。 回调 - 客户端发送某种形式的描述,如果事件发生,服务器应该做什么。这可能是指向 C 中的函数、.NET 中的委托或 WCF 中的端点架构的指针。服务器会记住该信息并在时间到来时从他们身边拨打电话。

如您所见,双工/回调意味着服务器在某些时候充当客户端(启动通信),这是一个重大的游戏改变。

WCF 双工通信可能需要特殊的网络配置,因为在许多情况下,网络允许您调用外部服务(您作为客户端工作)但禁止外部资源调用您(外部服务作为客户端工作)。这是出于安全目的而实施的。

回到你的问题:

    如果只需要下载大量数据,则不需要双工。如果您想捕获服务器中发生的更新并通知客户端,您可能需要它。 Duplex 应该适用于聊天,因为在聊天中有很多场景需要通知客户其他人引入的更改。 您所描述的是双工通道的手工变体。如果您希望服务器调用您的方法,您应该使用 MS 制作的经过验证和测试的双工实现。否则,您的选择是轮询。 你是对的,你需要tcp +流传输模式来处理大量数据。 TCP 使用二进制序列化,与文本序列化相比更紧凑 + 使用 TCP,您不需要发送任何 HTTP 标头或 SOAP 信封。如果不需要,请禁用安全性。它对性能有很大影响。

【讨论】:

【参考方案2】:

解决每个点:

1, 2. 我认为对于您的方案,双工服务是一种矫枉过正。正如您自己所说,当客户端和服务都需要不断地相互通知时,双工服务通常很方便,您正在做什么,将大量数据输入/输出数据库似乎并不是一个使用双工通信的好案例。关于netTcpBinding 不允许双工流式传输,您可以只返回一个字节数组 (byte[]) 而不是流。 40 MB 很多,但我认为流式传输不一定会比双工服务有显着的性能提升,后者将返回一个字节数组(由您测试每个设置并比较结果)。所以你在这里有几个选择,不要流式传输并返回一个字节数组(你可以用你的双工服务做到这一点)或者你可以忘记让你的服务双工,因为对你来说似乎没有一个强有力的案例使其成为双工并返回 Stream:

[OperationContract]
Stream RetrieveFile(long _fileId);
[OperationContract]
long SaveFile(Stream _stream);

3. netTcpBinding 与 HTTP 绑定相比具有相当大的性能优势,但它是有代价的,主要是因为它的 TCP 端口有时会被 Internet 防火墙阻止,尽管您可以使用 netTcpBinding在互联网上,不是recommended。选择绑定取决于您要做什么,如果您的客户端要通过 Internet 使用您的服务,那么 netTcpBinding 不是一个好主意(阻塞的 TCP 端口、防火墙等),但如果您的客户端是在同一网络 (LAN) 中使用服务,那么netTcpBinding 是最明智的选择。 wsDualHttpBinding(不支持流式传输:@)是一个不错的选择,如果您想坚持双工服务(相当于 Silverlight 中的 PollingDuplexHttpBinding),或者如果您放弃使用双工服务。

一些可能对您有所帮助的文章,各种 WCF 绑定的性能比较:

http://blog.shutupandcode.net/?p=1085

http://tomasz.janczuk.org/2010/03/comparison-of-http-polling-duplex-and.html

关于通过 HTTP 使用 WCF 流式传输大数据,据作者称,这两个样本都经过了高达 2GB 数据的测试:

http://garfoot.com/blog/2008/06/transferring-large-files-using-wcf/

http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP

你不应该认为你必须使用netTcpBinding或者你必须为你的服务使用流传输,netTcpBinding只有在你启用限制和配置一些套接字之后才会变得比HTTP绑定更高效级属性。与缓冲传输相比,流式传输 40 MB 不会有显着的性能提升。所以你有很多选择和很多权衡。没有黑白和对错之分,关键在于您如何定制服务以最好地满足您的需求,大多数解决方案都会奏效。你的场景很常见,网上有很多关于 WCF 中大数据传输的东西,做更多的研究;)

【讨论】:

嗯,我的实际需求是40MB左右的文件,但以后可能需要使用更大的文件,可能500-1000MB。另外我不明白为什么在聊天应用程序中双工合同和流的限制,今天在客户端之间发送文件并且可以是大文件是常见的。为什么要在良好的传输(流式传输)或双工应用程序之间进行选择? 我的猜测是来回通信不能很好地适应大量连续数据流的概念。也没有理由(我想就是这种情况)聊天本身是双工的,而文件通信是通过具有不同绑定的单独服务完成的。聊天服务器甚至可以通过双工频道发送通知“嘿,有一个文件供你下载,通过数据频道获取它” duplex+streaming的限制肯定有一些技术原因。在聊天应用程序中,您可以使用双工服务并将文件作为字节 [] 发送,实际上我之前已经这样做过,它适用于高达 100MB 的文件。在你的情况下,我认为你甚至不需要回调。看一下大文件传输的2个样本,显然都经过了高达2GB的测试,看了一眼代码,似乎并没有太难。

以上是关于何时使用双工服务?的主要内容,如果未能解决你的问题,请参考以下文章

在双工 WCF 服务的客户端中使用基于任务的异步模式时出错

使用 SignalR、WCF 双工服务和 ASP.Net 通用处理程序向客户端推送通知?

使用 net tcp 的 WCF 双工服务:“需要流安全性...”

使用WebSocket进行全双工通信

在c#中使用命名管道在两个进程之间进行双工操作

如何在 azure wcf 中继中处理双工 wcf