双工通信
1.设定服务契约和回调契约
服务契约中使用
[CallbackContract=typeof(XXXCallBackContractName)]
声明回调契约
OperationContract上可以使用[IsOnWay=true]来声明服务只提供单向来避免死锁,
也可以在ServiceContract上使用(ConcurrencyMode = ConcurrencyMode.Multiple)【多线程访问】
或(ConcurrencyMode = ConcurrencyMode.Reentrant)【单线程允许回调】
2.实现服务
服务端通过
#region 调用回调服务 XXXCallbackContractName callback = OperationContext.Current.GetCallbackChannel<XXXCallbackContractName>(); callback.XXXOperationContractName(XXXparmsList...); #endregion
来调用回调契约中的服务
3.双工Binding
在WCF预定义绑定类型中,WSDualHttpBinding和NetTcpBinding均提供了对双工通信的支持,
但是两者在对双工通信的实现机制上却有本质的区别。
WSDualHttpBinding是基于HTTP传输协议的;
而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的。
WSDualHttpBinding实际上创建了两个通道,一个用于客户端向服务端的通信,
而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。
而NetTcpBinding完全基于支持双工通信的TCP协议。
service
<system.serviceModel>
<services>
<service name="Service.Service" behaviorConfiguration="MyHttpGetBehaviors" >
<endpoint address="" binding="wsDualHttpBinding" contract="Contract.IService"></endpoint>
<endpoint address="net.tcp://localhost:7799/service" binding="netTcpBinding" contract="Contract.IService"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:7788/service"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyHttpGetBehaviors" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
client
<system.serviceModel>
<client>
<!--bindingConfiguration - 指定一个binding的配置名称,跟<bindings>下面同类<binding>的name匹配-->
<endpoint name="SubscriptionService"
address="http://localhost:7788/service"
binding="wsDualHttpBinding"
bindingConfiguration="wsDualHttpBinding_DuplexCalculator"
contract="Contract.IService"
/>
<!--Tcp实现的双工通信是使用同一个信道,因此不用重新指定Address-->
<!--Http的双工通信通过打开新信道和Service端通信,因此必须指定新的Address即ClientBaseAddress-->
<endpoint name="tcpService"
address="net.tcp://localhost:7799/service"
binding="netTcpBinding"
contract="Contract.IService"/>
</client>
<bindings>
<!--该Binding提供了Client的BaseAddress-->
<!--使用该Binding的EndPoint可以使用该Address进行Service和Client之间的双工通信-->
<wsDualHttpBinding>
<binding
name="wsDualHttpBinding_DuplexCalculator"
clientBaseAddress="http://localhost:8888/service"
/>
</wsDualHttpBinding>
</bindings>
</system.serviceModel>