双工服务
双工服务协定是一种消息交换模式,其中双方终结点都可独立向对方发送消息。因此,双工服务可以将消息发送回客户端终结点,从而提供类似事件的行为。当客户端连接到服务并为服务提供可用来将消息发送回客户端的通道时,就会发生双工通信。请注意,双工服务的类似事件的行为仅在会话中起作用。
若要创建双工协定,需要创建一对接口。第一个接口是描述客户端可调用的操作的服务协定接口。该服务协定必须在 System.ServiceModel.ServiceContractAttribute.CallbackContract 属性中指定一个回调协定。**回调协定是定义服务可在客户端终结点上调用的操作的接口。虽然系统提供的双工绑定利用了会话,但是双工协定不需要会话。
下面是双工协定的示例。
CalculatorService
类实现 ICalculatorDuplex
主接口。服务使用 PerSession 实例模式来维护每个会话的结果。名为 Callback
的私有属性访问指向客户端的回调通道。服务使用该回调通过回调接口将消息返送给客户端,如下面的示例代码所示。
客户端必须提供一个实现双工协定回调接口的类,以便从服务接收消息。下面的示例代码演示了一个实现 ICalculatorDuplexCallback
接口的 CallbackHandler
类。
针对双工协定生成的 WCF 客户端需要在构造时提供一个 InstanceContext 类。此 InstanceContext 类用作实现回调接口并处理从服务发送回的消息的对象所在的位置。InstanceContext 类是用 CallbackHandler
类的实例构造的。此对象处理通过回调接口从服务发送到客户端的消息。
服务的配置必须设置为提供同时支持会话通信和双工通信的绑定。wsDualHttpBinding 元素支持会话通信,并通过提供双 HTTP 连接(一个连接对应于一个方向)来允许进行双工通信。
在客户端,必须配置一个服务器可用来连接客户端的地址,如下面的示例配置所示。
提示
未能使用安全会话通过身份验证的非双工客户端通常会引发 MessageSecurityException。但是,如果使用安全会话的双工客户端未能通过身份验证,客户端则收到 TimeoutException。
如果使用 WSHttpBinding 元素创建客户端/服务,并且不包含客户端回调终结点,您将收到以下错误。
HTTP could not register URL
htp://+:80/Temporary_Listen_Addresses/<guid> because TCP port 80 is being used by another application.
下面的示例代码演示了如何在代码中指定客户端终结点地址。
WSDualHttpBinding binding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("https://localhost:12000/DuplexTestUsingCode/Server");
binding.ClientBaseAddress = new Uri("https://localhost:8000/DuplexTestUsingCode/Client/");
下面的示例代码演示了如何在配置中指定客户端终结点地址。
<client>
<endpoint name ="ServerEndpoint"
address="https://localhost:12000/DuplexTestUsingConfig/Server"
bindingConfiguration="WSDualHttpBinding_IDuplexTest"
binding="wsDualHttpBinding"
contract="IDuplexTest" />
</client>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IDuplexTest"
clientBaseAddress="https://localhost:8000/myClient/" >
<security mode="None"/>
</binding>
</wsDualHttpBinding>
</bindings>