WCF全双工通信实例分享(wsDualHttpBinding、netTcpBinding两种实现方式)
最近在研究WCF通信,如果没有接触过的可以看我的前一篇文章:https://www.cnblogs.com/xiaomengshan/p/11159266.html 主要讲的最基础的basicHttpBinding方式的单工WCF通信,步骤比较详细,所以本文就只说明关键的细节,详细的步骤操作可以参考前一篇文章,还望理解。本文使用的环境是VS2015,使用的项目都是WPF,如使用Winform、Web项目的可能有些细微的差别,不过原理应该差不多,各位可以自己调试一下。
全双工的方式主要是依靠回调客户端函数的方式实现,可以构造数据包处理接口来实现常规C/S架构,也可以搭建发布/订阅机制的系统,看具体使用了。平时新建的WCF服务默认是basicHttpBinding方式的单工方式,支持全双工的有wsDualHttpBinding、netTcpBinding及mexNamedPipeBinding。wsDualHttpBinding通过建立两条Http协议的方式实现全双工;netTcpBinding使用的net.tcp协议进行通信;mexNamedPipeBinding采用net.pipe的方式,但是该方式好像只支持同一系统间不同进程的通信。当然还支持很多其他的方式,不过每去研究。本文只分享wsDualHttpBinding、netTcpBinding方式的通信案例,因为其他的我自己没实际测试过,不敢误导大家。
wsDualHttpBinding实现全双工
一、服务器端
1、创建WCF服务
自动生成IMyWCFBothway.cs与MyWCFBothway.cs
2、编写服务契约接口
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack))]
public interface IMyWCFBothway
{
[OperationContract]
string DoWork(string msg);
}
注:
1、CallbackContract = typeof(ICallBack))即为声明回调契约为ICallBack
2、[OperationContract]如不声明则客户端引用服务时对该接口函数不可见
3、编写回掉契约接口
public interface ICallBack
{
[OperationContract(IsOneWay = true)]
void ClientCallBack(string msg);
}
注:
1、[OperationContract(IsOneWay = true)] 声明单向后该接口函数不支持输出,即不能设置返回值和ref/out传入引用
2、该接口服务器端不需实现,但需要在客户端实现
4、实现服务契约接口
public class MyWCFBothway : IMyWCFBothway
{
public string DoWork(string msg)
{
string Str = msg + "访问服务器成功";
//获取客户端实现回调接口的子类实例
ICallBack iCallBack = OperationContext.Current.GetCallbackChannel<ICallBack>();
Console.WriteLine(msg+"访问服务器");
Console.WriteLine(msg + "服务器执行回调");
//执行客户端的回调函数
iCallBack.ClientCallBack("服务器执行回调成功");
Console.Read();
return Str;
}
}
注:
1、如需回调客户端函数,需要使用OperationContext.Current.GetCallbackChannel<T> 获取客户端实现回调接口实例
5、修改配置文件
<service name="WCFServer.MyWCFBothway">
<endpoint address="" binding="wsDualHttpBinding" contract="WCFServer.IMyWCFBothway">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/" />
</baseAddresses>
</host>
</service>
</services>
注:
1、主要修改使用的方式改为wsDualHttpBinding 2、http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/ 就为客户端服务引用的链接 3、本地测试可以使用localhost,如发布服务器需改为服务器IP 4、端口修改有时会报权限不足,可以将VS用管理员权限打开再编译
6、启动服务
ServiceHost host1 = new ServiceHost(typeof(WCFServer.MyWCFBothway));
host1.Open();
二、客户端
1、引用WCF服务
通过服务引用引用WCF服务:http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/
2、实现回调契约接口
[CallbackBehavior(UseSynchronizationContext = false)]
public class MyClientCallBack: IMyWCFBothwayCallback
{
public void ClientCallBack(string msg)
{
Console.WriteLine(msg);
Console.Read();
}
}
注:
1、实现的回调接口为IMyWCFBothwayCallback,而不是服务器声明的ICallBack,可以在引用服务后使用对象查看器查看,中间应该是经过代理把名称统一换了
2、需要声明[CallbackBehavior(UseSynchronizationContext = false)],否则回调回失败,感觉像找不到回调函数还是阻塞了就超时了
3、访问WCF服务
//声明回调实现类实例
MyClientCallBack CallBack = new MyClientCallBack();
//使用回调实现类实例创建会话实例
InstanceContext context = new InstanceContext(CallBack);
//创建WCF服务实例,传入会话实例给服务器是为了方便服务器通过该会话进行回调
WCFBothway.MyWCFBothwayClient W = new MyWCFBothwayClient(context);
//访问WCF服务
string msg = W.DoWork("客户端1");
Console.WriteLine(msg);
Console.Read();
netTcpBinding实现全双工
其实netTcpBinding方式与wsDualHttpBinding方式用法基本相同,区别只是在一些配置上面,所以下面只说明其中的不同点就不一步步详细冗余说明了。
服务契约接口实现:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WCFNetTcp : IWCFNetTcp
{
public string DoWork(string msg)
{
Console.WriteLine(msg + "访问服务器");
Console.Read();
//获取客户端实现回调接口的子类实例
ICallBackNetTcp iCallBack = OperationContext.Current.GetCallbackChannel<ICallBackNetTcp>();
iCallBack.CallBack("执行回调");
string Str = msg + "访问服务器成功";
return Str;
}
}
注:这个要声明[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)],不然会报错
App.config:
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors> <service name="WCFServer.WCFNetTcp">
<endpoint address="" binding="netTcpBinding" contract="WCFServer.IWCFNetTcp">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" />
</baseAddresses>
</host>
</service>
主要修改的是配置文件:
1、serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" 可能是不使用Http协议的原因,这两个选项要置为false
2、binding="netTcpBinding"要指定netTcpBinding方式
3、binding="mexTcpBinding"指定使用Tcp方式
4、net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" 要将前缀声明为net.tcp协议
其余部分的实现和wsDualHttpBinding方式基本相同~
这次测试了这两种全双工方式的WCF通信,感觉WCF还是很强大方便的,但是还有很多参数不大清楚,只是使用的默认参数,还需继续去研究。
最新文章
- 小规模的流处理框架.Part 1: thread pools
- AMR 转mp3 失败
- ADS1.2安装教程
- JSON和JS对象之间的互转(转)
- LeetCode Integer to English Words
- BZOJ2435: [Noi2011]道路修建
- jquery easyui的方法参数
- 内联函数 inline
- Vmware Vsphere WebService之vijava 开发一-vcenter连接、及集群信息获取
- 从实践的角度理解cookie的几个属性
- 【转】磁盘I/O那些事
- JavaScript获取、修改CSS样式合辑
- DIV或者DIV里面的图片水平与垂直居中的方法
- visual studio 2017 installer 安装包的安装必备组件设置
- boke例子: freermarker:在使用ajax传递json数据的时候多出冒号
- MyBatis框架介绍及其实操
- kettle学习笔记(五)——kettle输出步骤
- jdbc连接池c3p0/dbcp强制连接超过设置时间后失效
- 智能跳转---TC资源管理器
- II、Python HelloWorld
热门文章
- workerman连接失败方法
- 基于node.js人脸识别之人脸对比
- SpringBoot2.0 整合 FastDFS 中间件,实现文件分布式管理
- mysql的repeat()函数
- Docker Compose file
- 教你用Python实现免费蹭WiFi,只要有WiFi的地方,你就不会断网!
- 并发容器之ConcurrentLinkedQueue
- 爬虫最新的库requests-html库总结
- Initialize a Property After Creating an Object 创建对象后初始化属性 (XPO)
- scrapy实例:爬取天气、气温等