【问题标题】:How are callbacks implemented in WCF?WCF 中的回调是如何实现的?
【发布时间】:2010-12-06 22:42:56
【问题描述】:

进行异步 WCF 服务调用时,服务能够(并且必须)执行收到的回调。这在一般 APM 中是有意义的,但在 WCF 情况下,回调实际上是在客户端执行的,这意味着服务器本质上能够执行客户端代码。

有人能解释一下这是如何实现的吗?例如,当使用 http 绑定时,当服务执行回调时,它是否开始发回一个 http 响应,WCF 客户端将其反序列化为执行回调的消息,并且响应通过返回的 End 方法完成异步操作?服务能否调用两次回调

谢谢!

编辑: 只是为了确保它们不会混淆,我不是在询问带有双工合同的回调,而是 AsyncCallback 在合同中传递,如下所示(http://msdn.microsoft.com/en-us/library/ms731177.aspx ):

  [OperationContractAttribute(AsyncPattern=true)]
  IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState);

  // Note: There is no OperationContractAttribute for the end method.
  string EndServiceAsyncMethod(IAsyncResult result);

【问题讨论】:

  • +1 现在我了解到您在询问服务端操作的异步实现,我意识到“什么是回调参数”和“服务实现应该遵循什么规则使用它——例如,如果我调用它两次会发生什么?”是非常有趣的问题。请参阅piers7.blogspot.com/2009/09/… 了解更多信息。我认为有一点很清楚:回调不会调用客户端代码 - 它是 WCF 服务调度程序堆栈中的代码。

标签: .net wcf


【解决方案1】:

使用 HTTP 协议的回调被实现为复合双工通信 (WS-DualHttpBidning)。这意味着双方在不同的传输连接上相互调用。当客户端调用服务时,它会发送 HTTP 请求。服务处理请求并存储回调通道供以后使用。然后它返回仅确认发起请求的 HTTP 响应。它不会触发回调。回调是通过调用回调通道上的操作从服务触发的。它创建从服务器发送到客户端的 HTTP 请求。客户端执行回调操作并向服务器返回 HTTP 响应。

此通信流程使用双向消息交换模式,但双工通信通常使用单向消息传递。服务器可以根据需要多次调用客户端回调(客户端的性能和不活动超时会影响这一点)。

复合双工通信要求客户端和服务器都可以访问(双方的防火墙设置)。在 HTTP 上,客户端暴露了自己的端点,其行为类似于另一个 Web 服务。相比之下 net.tcp 具有全双工通信通道,因此服务器调用和回调 cqlls 都在同一个 TCP 连接上执行。

编辑:

对不起,我没听懂你的问题。异步操作(AsyncPattern)在服务器上实现 - 实现对客户端完全透明(由 WCF 服务架构包装)。客户端以常见的 HTTP 请求/响应模式进行通信,服务只能为每个请求发送单个响应。

WCF 支持两个级别的异步处理 - 异步调用和异步操作。前者实现在客户端,服务不知道,后者实现在服务,客户端不知道。这些方法经常结合在示例中,这可能会造成混淆。

每种方法都有自己的特点。异步调用允许非阻塞服务调用,其中客户端可以在服务处理请求时执行其他操作(UI 不会冻结)。异步操作是为了更好地扩展大量使用的服务。同步执行会阻止 WCF 处理线程,直到执行完成,而异步执行允许将处理线程返回到线程池(因此它可以处理另一个请求),而操作执行一些耗时的操作 - 通常是 IO 或网络通信。

【讨论】:

  • 这听起来不对 - 所以异步 wcf 操作默认是双工通信?我虽然 wcf 让您将合同明确定义为双工合同。这与我上面评论的问题相同(权限、防火墙等),你确定吗?
【解决方案2】:

本质上,通信与服务器调用相同。 “客户端”端基本上有一个带有回调合约的端点,以便“服务器”可以调用它。没有魔法。

【讨论】:

  • 这听起来不对 - 你是说服务器执行客户端的回调,它创建另一个http请求并将其发送给客户端?如果客户端无权打开套接字并侦听传入请求怎么办?如果客户端位于路由器/防火墙/等后面怎么办?
  • 试试吧。如果没有沟通机制,就不会发生。
【解决方案3】:

WCF 客户端堆栈在收到来自服务器的 HTTP 响应时调用回调方法。正如 Alex Lo 所说,服务器对此一无所知 - 它甚至不知道客户端代码正在使用异步调用:它所看到的只是一个 HTTP 请求。

我没有研究过血腥的细节,但我想回调是在 IO 完成端口上进行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多