1. 使用管理员权限打开VS2017

  2. 创建一个空白解决方案:

3. 创建几个基于.net  framework的类库项目和一个基于.net Framework 的控制台项目, 然后将类库项目的class1.cs文件删除, 整体如下图:

   

4. 为每个类库添加对应的类文件:

  a)         MyWCF.WCFSimpleDuplex.Interface添加两个接口, ICalculatorService和ICallBack, 其中ICalculatorService表示要启动的服务接口, 而ICallBack表示要回调客户端时, 访问的接口

  b)         ICalculatorService 代码如下:

using System.ServiceModel; namespace MyWCF.WCFSimpleDuplex.Interface
{/// <summary>/// 定义协议的时候, 同时需要定义一个回调接口/// 示例中定义服务契约的同时定义一个回调接口ICallBack/// 双工中的函数不能带返回值/// 如果你实在想要返回值, 那么自己用out/// </summary>[ServiceContract(CallbackContract = typeof(ICallBack))]public interface ICalculatorService{/// <summary>/// 添加isoneway属性表示, 这个函数是不是返回应答信息 ; /// </summary>/// <param name="x"></param>/// <param name="y"></param>[OperationContract(IsOneWay = true)]void Plus(int x, int y);//建立了一个Icalculator服务的协议//这个协议带有一个回调接口ICallBack//注意WCF的双工, 不能全靠配置, 在建立服务的时候, 就要开始处理了}
}

  

c)         ICallBack代码如下

using System.ServiceModel;namespace MyWCF.WCFSimpleDuplex.Interface
{/// <summary>/// 不需要协议, 因为它不是一个服务契约, 它只是一个约束,这个约束由客户端实现/// </summary>public interface ICallBack{/// <summary>/// 这里就是回调的时候完成的函数, 这个接口也要加上Isoneway=true  /// </summary>/// <param name="m"></param>/// <param name="n"></param>/// <param name="result"></param>[OperationContract(IsOneWay = true)]void Show(int m, int n, int result);}//要发布一个双工协议 ,首先在服务的建立WCF服务, 服务的契约上面指定callbackContract回调的类型//建立回调接口, 回调接口就是等下要执行的接口
}

  

5. 接下来处理 MyWCF.WCFSimpleDuplex.Model 的代码, 它就一个类:

using System.Runtime.Serialization;namespace MyWCF.WCFSimpleDuplex.Model
{[DataContract]public class WCFUser{//[DataMember]public int Id { get; set; }[DataMember]public int Age { get; set; }[DataMember]public int Sex { get; set; }[DataMember]public string Name { get; set; }[DataMember]public string Description { get; set; }}public enum WCFUserSex{Famale,Male,Other}
}

  

6. 关于服务类MyWCF.WCFSimpleDuplex.Service的处理如下:

using System.ServiceModel;
using MyWCF.WCFSimpleDuplex.Interface;namespace MyWCF.WCFSimpleDuplex.Service
{/// <summary>/// 对ICalculatorService的一个实现类; 实现的时候, 除了要完成自己的计算, 还要完成, 对接口的回调/// </summary>public class CalculatorService : ICalculatorService{/// <summary>/// 完成计算,然后去回调/// </summary>/// <param name="x"></param>/// <param name="y"></param>public void Plus(int x, int y){int result = x + y;System.Threading.Thread.Sleep(3000);//OperationContext表示当前操作的上下文//OperationContext.Current.GetCallbackChannel<ICallBack>();这里有点像IOC, 给你一个接口然后生成一个实例; 注意哦, 这里的ICallBack还有没有任何实现, 而这个实现是在客户端(client)处去完成的ICallBack callBack =OperationContext.Current.GetCallbackChannel<ICallBack>();callBack.Show(x, y, result);}}
} 

7.       接下来是控制台MyWCF.WCFSimpleDuplex.ConsoleTest的代码实现, 首先是他的配置文件

a)         初始时的配置文件如下图: 

b)         在configuration节点添加如下配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup><system.serviceModel>  <!--WCF的配置文件 , WCF的配置文件一个是基于TCP的, 一个是基于http的; 可以添加多个; 如果添加多个就是下面的配置格式 --><behaviors> <serviceBehaviors><!--<behavior name="MathServicebehavior"> --><!--这里配置第一个Behavior的节点--><!--<serviceDebug httpHelpPageEnabled="false"/><serviceMetadata httpGetEnabled="false"/><serviceTimeouts transactionTimeout="00:10:00"/><serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/></behavior>--><behavior name="CalculatorServicebehavior">  <!--这里配置第二个Behavior的节点--><serviceDebug httpHelpPageEnabled="false"/><serviceMetadata httpGetEnabled="false"/><serviceTimeouts transactionTimeout="00:10:00"/><serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/></behavior></serviceBehaviors></behaviors><!--在tcp中上面几行和http的配置都是一样的-->  <bindings><netTcpBinding><binding name="tcpbinding">   <!--指定为tcp的协议类型-->  <security mode="None"><!--clientCredentialType="None" → 表示加密类型  protectionLevel="None"  表示安全级别--><transport clientCredentialType="None" protectionLevel="None"/></security></binding></netTcpBinding></bindings><services> <service name="MyWCF.WCFSimpleDuplex.Service.CalculatorService" behaviorConfiguration="CalculatorServicebehavior"><host> <!--这里配置第一个服务的名称和服务的具体指向类--><baseAddresses><add baseAddress="net.tcp://localhost:9999/CalculatorService"/><!--指定的协议为net tcp协议--></baseAddresses></host><endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="MyWCF.WCFSimpleDuplex.Interface.ICalculatorService"/><endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/></service><!--<service name="MyWCF.WCFSimpleDuplex.Service.MathService" behaviorConfiguration="MathServicebehavior"><host>--><!--这里配置第二个服务的名称和服务的具体指向类--><!--<baseAddresses><add baseAddress="net.tcp://localhost:9999/MathService"/></baseAddresses></host><endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="MyWCF.WCFSimpleDuplex.Interface.IMathService"/><endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/></service>--></services></system.serviceModel>
</configuration>

c)         Program代码如下:

 

using System;
using System.ServiceModel;
using MyWCF.WCFSimpleDuplex.Service;namespace MyWCF.WCFSimpleDuplex.ConsoleTest
{class Program{static void Main(string[] args){try{Console.WriteLine("开始挂起服务");ServiceInit.Process();}catch (Exception ex)//如果报无法注册. . ., 则说明需要管理员权限, 启动这个程序{//服务“SOA.WCF.Service.CalculatorService”有零个应用程序(非基础结构)终结点。这可能是因为未找到应用程序的配置文件,或者在配置文件中未找到与服务名称匹配的服务元素,或者服务元素中未定义终结点。//没有配置文件//另一应用程序已使用 HTTP.SYS 注册了该 URL。//端口 9999 被其它应用程序占用了, 找到并将其停止Console.WriteLine(ex.Message);}Console.Read();}}/// <summary>/// WCF寄宿到控制台/// </summary>public class ServiceInit{public static void Process(){//ServiceHost →表示提供服务的主机,使用服务的类型及其指定的基址初始化 System.ServiceModel.ServiceHost 类的新实例。Type type = typeof(CalculatorService);ServiceHost host =  new ServiceHost(type);host.Opening += (s, e) => Console.WriteLine($"{type} 准备打开");//已经打开事件host.Opened += (s, e) => Console.WriteLine($"{type} 已经正常打开");//开启服务; 注意当这里需要Open的时候, 会去配置文件中检查是否有配置了MathService这个类的behavior(行为)host.Open();Console.WriteLine("输入任何字符,就停止");Console.Read();host.Close();Console.Read();}}}

 

8. 完成以上步骤就可以启动试试看了:

9. 可以使用  cmd 命令 netstat -ano | find "9999", 查看下端口9999是否被监听

10. 双工的服务端已经处理完毕, 接下来开始处理客户端, 当然客户端首先就要对刚才的ICallBack进行实现, 这个毋容置疑的

11. 再新打开一个VS2017, 创建一个控制台测试项目:

12. 接下来不用多想, 第一件事, 添加服务引用, 第二件事实现服务端的那个ICallBack接口

a)         添加服务引用

b)         实现ICallBack接口, 注意这个类里的Show 方法, 在客户端没有任何代码调用

using System;namespace MyWCF.WCFSimpleDuplexConsoleTest.CTest
{/// <summary>/// 具体实现的回调/// </summary>public class CallBackService : MyDuplexConsoleTest.ICalculatorServiceCallback{public void Show(int m, int n, int result){Console.WriteLine($"回调操作展示, 这个操作发生在两秒之后:{m}+{n}={result}");}}
}

  

c)         整体client截图:

13. 然后在program中的代码, 建议单步调试看看代码的运行过程:

using System;
using System.ServiceModel;namespace MyWCF.WCFSimpleDuplexConsoleTest.CTest
{class Program{static void Main(string[] args){MyDuplexConsoleTest.CalculatorServiceClient client = null;try{Console.WriteLine("客户端来测试双工!~~");//创建一个需要回调的实例, 等会服务端进行回调的InstanceContext context = new InstanceContext(new CallBackService());client = new MyDuplexConsoleTest.CalculatorServiceClient(context);client.Plus(123, 234);client.Close();}catch (Exception ex){if (client != null)client.Abort();Console.WriteLine(ex.Message);}Console.Read();}}
}

14. 结果截图

  

15. 结束

转载于:https://www.cnblogs.com/wxylog/p/9895442.html

20181102_WCF简单双工相关推荐

  1. 《视频解密》中文版(第四版) 第六章 数字视频接口(第三部分)

    视频模块接口(VMI) 视频模块接口(VMI)开发用于不同多媒体IC生产商的互联.它的目标是如MPGE解码器,NTSC/PAL解码器和图像芯片的视频接口标准化. 图6.39 VMI 8比特 4:2:2 ...

  2. 进程间通信:同步双工管道

    因为工作需要,需要设计出一个双工的IPC.(转载请指明出处)在一番比较后,我发现管道是比较符合我们的需求的.但是我们需求要求管道的对方是可信任的,而在vista以下系统是没有GetNamedPipeC ...

  3. 【转】利用WCF的双工通信

    Silverlight与WCF之间的通信(2)利用WCF的双工通信"推送"给SL数据 作者:Leon Weng  来源:博客园  发布时间:2010-06-19 23:43  阅读 ...

  4. Wcf 双工通信的应用

    概述 双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工ME ...

  5. 对CAN、USART、SPI、SCI等常见总线的简单介绍

     任何一个微处理器都要与一定数量的部件和外围设备连接,但如果将各部件和每一种外围设备都分别用一组线路与CPU直接连接,那么连线将会错综复杂,甚至难以实现.为了简化硬件电路设计.简化系统结构,常用一 ...

  6. 利用WCF的双工通讯实现一个简单的心跳监控系统

    何为心跳监控系统? 故名思义,就是监控某个或某些个程序的运行状态,就好比医院里面的心跳监视仪一样,能够随时显示病人的心跳情况. 心跳监控的目的是什么? 与医院里面的心跳监视仪目的类似,监控程序运行状态 ...

  7. TCP/IP 协议简单分析(建立连接握手过程)

    原文:http://hi.baidu.com/wuguoyana/blog/item/38c04d3bcf047ce43a87ce55.html 首先TCP和IP是两种不同的协议,它们来七层网络模型中 ...

  8. 分布式系统的消息服务模式简单总结

    在一个分布式系统中,有各种消息的处理,有各种服务模式,有同步异步,有高并发问题甚至应对高并发问题的Actor编程模型,本文尝试对这些问题做一个简单思考和总结. 一.消息的"推.拉模式&quo ...

  9. websocket 学习--简单使用,nodejs搭建websocket服务器,到模拟股票,到实现聊天室

    websocket简介: WebSocket协议是 HTML5 开始提供的一种基于TCP的一种新的全双工通讯的网络通讯协议.它允许服务器主动发送信息给客户端. 和http协议的不同?? HTTP 协议 ...

最新文章

  1. 2016.04.09 使用Powerdesigner进行创建数据库的概念模型并转为物理模型
  2. mysql 主从有哪几种模式_mysql 主从模式总结(一)
  3. 机器学习基础专题:感知机
  4. Hadoop常用操作汇总
  5. Verilog代码风格
  6. 875. 爱吃香蕉的珂珂(二分)
  7. 工作194:vue.runtime.esm.js?2b0e:619 [Vue warn]: Duplicate keys detected: ‘/system‘. This may cause an
  8. Hibernate缓存和加强
  9. java 反射 动态编译_动态编译java源代码和反射调用问题
  10. 颜色和心理年龄测试软件,超准的色彩心理学:选8个颜色,就可以测出你的心理年龄...
  11. Matlab期货量化交易特征选取,【策略分享】Matlab量化交易策略源码分享
  12. bootstrap dialog
  13. h5 a标签下载链接下载文件
  14. 【栈】实现逆波兰计算器
  15. 2.5数字传输系统2.6宽带接入技术
  16. BI财务分析 – 反映盈利水平利润占比的指标如何分析(上)
  17. eyoumailserver邮箱服务器与foxmail 邮箱客户端的使用和安装
  18. 小红书SEO之关键词排名优化详解【从入门到精通】
  19. C++报错:引发了未经处理的异常:写入访问权限冲突, p 是 0xCCCCCCCC
  20. 在idea中如何导入一个已有的项目

热门文章

  1. django mysql返回json_Django 1.8.11 查询数据库返回JSON格式数据
  2. mysql导入错误_mysql导入sql文件出错的一种解决方法
  3. k均值聚类的python代码_k-均值聚类Python代码实现
  4. java线程间通信 实例_JAVA-初步认识-第十四章-线程间通信-示例
  5. android数据绑定_Android数据绑定
  6. Node JS和MongoDB的集成简单示例
  7. Java中的System.exit()
  8. Elasticsearch的javaAPI之get,delete,bulk
  9. 在微服务中,Kubernetes软件组件有哪些?
  10. 人工智能时代,技术人员应该掌握的技能