HTTP与Tcp协议下双工通信的差异
WCF中经常会使用HTTP协议与Tcp协议来实现双工通讯,对应使用的协议分别为WsDualHttpBinding、NetTcpBinding。
HTTP是基于应用层的协议,而Tcp是基于传输层的协议。Tcp经过三次握手建立起客户端到服务端的可靠连接,发起请求的客户端与回调客户端的服务端都使用一个连接就能完成。使用HTTP协议时,从客户端到服务端发起请求到服务端返回给客户端回复完成后,连接就关闭。
由于HTTP的这种无连接性,基于WsDualHttpBinding的双工在进行通讯时实际上服务端在回调客户端时,会与NetTcpBinding在使用上有些差异。
1、NetTcpBinding实现双工
1.1契约部分:
1.1.1 契约接口定义:
[ServiceContract(CallbackContract = typeof (ICallback))]
public interface ICalculator
{
[OperationContract]
void Add( double x, double y);
}
1.1.2 回调接口定义:
public interface ICallback
{
[OperationContract]
void Display( double x, double y , double result);
}
1.2服务实现:
public void Add( double x, double y)
{
Console.WriteLine( " 开始Add计算 " );
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.Display(x, y, x + y);
Console.WriteLine( string .Format( " {0},{1} " , x, y));
}
服务通过OperationContext.Current.GetCallbackChannel<T>泛型方法获取对客户端回调代理类,对客户端进行回调
public T GetCallbackChannel<T>()
{
if (( this .channel != null ) && ! this .IsUserContext)
{
return (T) this .channel.Proxy;
}
return default (T);
}
1.3 服务端配置:
<system.serviceModel>
<services>
<service name= " Services.CalculatorServices " >
<endpoint address= " Calaulator " binding= " netTcpBinding " contract= " Contract.ICalculator " ></endpoint>
<host>
<baseAddresses>
<add baseAddress= " net.tcp://127.0.0.1:6688 " />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
1.4 客户端部分:
回调接口的实现:
public void Display( double x, double y, double result)
{
Console.WriteLine( string .Format( " {0}+{1}={2} " , x, y, result));
}
客户端配置:
<system.serviceModel>
<client>
<endpoint address= " net.tcp://127.0.0.1:6688/Calaulator " binding= " netTcpBinding " contract= " Contract.ICalculator " name= " calculatorTcp " ></endpoint>
</client>
</system.serviceModel>
接口调用:
InstanceContext context = new InstanceContext( new CallBack());
using ( var channelFactory = new DuplexChannelFactory<ICalculator>(context, " calculatorTcp " ))
{
ICalculator proxy = channelFactory.CreateChannel();
proxy.Add( 1.0 , 2.0 );
Console.ReadLine();
}
结果如下图:
服务端:
客户端:
2、WsDualHttpBinding实现双工。
同样以上面的契约为例.在数据包、或者请求-响应模式中,如果更换协议一般只需更改所使用的绑定即可。我们将客户端配置改为如下:
<system.serviceModel>
<client>
<endpoint address= " http://127.0.0.1:8866/Calaulator/ws " binding= " wsDualHttpBinding " contract= " Contract.ICalculator " name= " calculatorWsDual " ></endpoint>
</client>
</system.serviceModel>
然后使用calculatorWsDual重新生成ChannelFactory:
using ( var channelFactory = new DuplexChannelFactory<ICalculator>(context, " calculatorWsDual " ))
运行调试:有如下异常:
解决办法为Endpoint配置绑定行为,如下:
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name = " myWsDualBinding " clientBaseAddress= " http://127.0.0.1:3636/Service/CallbackService " ></binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address= " http://127.0.0.1:8888/Service/Calculator " binding= " wsDualHttpBinding " contract= " Contracts.ICalculator " name= " calculatorService " bindingConfiguration= " myWsDualBinding " />
</client>
</system.serviceModel>
这样,问题就得以解决
分类: WCF基础
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于HTTP与Tcp协议下双工通信的差异的详细内容...