最近在研究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还是很强大方便的,但是还有很多参数不大清楚,只是使用的默认参数,还需继续去研究。

WCF全双工通信实例分享(wsDualHttpBinding、netTcpBinding两种实现方式)的更多相关文章

  1. Java学习-014-文本文件写入实例源代码(两种写入方式)

    此文源码主要为应用 Java 读取文本文件内容实例的源代码.若有不足之处,敬请大神指正,不胜感激! 第一种:文本文件写入,若文件存在则删除原文件,并重新创建文件.源代码如下所示: /** * @fun ...

  2. Android进程通信之一:两种序列化方式

    2月下旬辞职了,去海南度假到现在,领略了一把三亚风情也算任性和 然而这样任性带来的后果就是..不行了我必须吐槽一句.. 没毕业的找工作就这么难嘛!投了57家一家面试机会都没有,好歹给个面试机会啊!!本 ...

  3. struts2+spring的两种整合方式

    也许有些人会因为学习了struts1,会以为struts2.struts1与spring的整合也是一样的,其实这两者相差甚远.下面就来讲解一下struts2与spring的整合两种方案.(部分转载,里 ...

  4. 第一章 Mybtais的两种启动方式

    Mybatis的两种启动方式如下: 1.xml实现: xml的实现方式中,主要是通过手动创建SqlSession,然后调用session.selectOne()方法实现来实现. 首先是创建Config ...

  5. Adobe Acrobat XI Pro 两种破解方式 Keygen秘钥 license替换 亲测有效

    大家平时看paper比较多的话想必都是用Adobe Acrobat而非Adobe Reader吧,其功能全面之处就不啰嗦了,下面给大家分享下Adobe Acrobat XI Pro的两种破解方式(两种 ...

  6. Java中匿名类的两种实现方式(转)

    使用匿名内部类课使代码更加简洁.紧凑,模块化程度更高.内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到.然而这个不是我说的重点,我说的很简单,就是匿名内部类的两种实现方式 ...

  7. 动态代理的两种实现方式(JDK/Cglib)

    =========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...

  8. Java中String对象两种赋值方式的区别

    本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...

  9. Oracle数据库日期范围查询的两种实现方式

    参考文档:http://database.51cto.com/art/201108/288058.htm Oracle数据库日期范围查询有两种方式:to_char方式和to_date方式,接下来我们通 ...

随机推荐

  1. 通过jgit一次性升级fastjson版本

    背景:笔者所在公司经历了三次fastjson的升级,由于集群,工程数量众多,每次升级都很麻烦.因此开发了一个java的升级工具. 功能介绍: 功能介绍:一个jar文件,通过java -jar命令,输入 ...

  2. 【开发工具】IDEA简明使用指南

    目录 1. 搭建idea的开发环境 2. 调试技巧 3. 常用快捷键(小技巧) 4. 插件推荐 工欲善其事,必先利其器.在Java开发中挑选一款好的Ide环境能大大提升我们的开发效率,IntelliJ ...

  3. 程序员修神之路--redis做分布式锁可能不那么简单

    菜菜哥,复联四上映了,要不要一起去看看? 又想骗我电影票,对不对? 呵呵,想去看了叫我呀 看来你工作不饱和呀 哪有,这两天我刚基于redis写了一个分布式锁,很简单 不管你基于什么做分布式锁,你觉得很 ...

  4. SpringCloud的入门学习之概念理解、Ribbon负载均衡入门

    1.Ribbon负载均衡,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端.负载均衡的工具. 答:简单的说,Ribbon是Netflix发布的开源项目,主要功能 ...

  5. Python中常见的8种数据结构的实现方法(建议收藏)

    数据结构作为计算机基础的必修内容,也是很多大型互联网企业面试的必考题.可想而知,它在计算机领域的重要性. 然而很多计算机专业的同学,都仅仅是了解数据结构的相关理论,却无法用代码实现各种数据结构. 栈 ...

  6. Java - 运算符 方法

    本位是复习笔记,不适合零基础 赋值运算符 变量 名称 = 值/表达式 ; 需要注意的是,赋值运算符的计算是按照从右往左的; 注意: 1.在使用赋值符号时,必须保证左侧的类型范围大于等于右侧产生的类型 ...

  7. MySQLl存储过程学习总结

    1.简介 : 逻辑处理一般不是一条语句组成,需要多条之间相互配合使用              这时,存储过程就是为了以后使用而保存的的一条或多条Mysql语句的集合 2.为何 : 1)简单:将处理单 ...

  8. $和jquery的关系

    $和jquery的关系 $其实是jQuery的别名 一般直接使用$符号 在许多JavaScript库中都会有$作为标记.如果同时使用多个JavaScript库时难免会出现冲突. 解决方法:重新设置jQ ...

  9. 那些你不知道的Mac截屏功能

    今天介绍Mac的截图功能,如果你以为Shift + Command + 3 / 4就是Mac全部的截屏功能的话,那你小看Mac了.它远比你想得强大. 1.Shift + Cmd + 3 ——截取全屏 ...

  10. QT解决中文乱码

    如果编译器在支持C++11的情况下,我们可以使用u8"XXXX" 如:QString str = u8"我是中文"; 这样就解决了中文乱码的问题,使用UTF-8 ...