• 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、编写服务契约接口

    1 [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack))] 
    2     public interface IMyWCFBothway
    3     {
    4         [OperationContract]
    5         string DoWork(string msg);
    6     }

     注:

    1、CallbackContract = typeof(ICallBack))即为声明回调契约为ICallBack

    2、[OperationContract]如不声明则客户端引用服务时对该接口函数不可见

    3、编写回掉契约接口

    1   public interface ICallBack
    2     {
    3         [OperationContract(IsOneWay = true)]
    4         void ClientCallBack(string msg);
    5     }
    注:
    1、[OperationContract(IsOneWay = true)] 声明单向后该接口函数不支持输出,即不能设置返回值和ref/out传入引用
    2、该接口服务器端不需实现,但需要在客户端实现

    4、实现服务契约接口

     1 public class MyWCFBothway : IMyWCFBothway
     2     {       
     3         public string DoWork(string msg)
     4         {
     5             string Str = msg + "访问服务器成功";
     6             //获取客户端实现回调接口的子类实例
     7             ICallBack iCallBack = OperationContext.Current.GetCallbackChannel<ICallBack>();             
     8             Console.WriteLine(msg+"访问服务器");
     9             Console.WriteLine(msg + "服务器执行回调");   
    10             //执行客户端的回调函数         
    11             iCallBack.ClientCallBack("服务器执行回调成功");
    12             Console.Read();
    13             return Str;
    14         }
    15     }
    注:
    1、如需回调客户端函数,需要使用OperationContext.Current.GetCallbackChannel<T> 获取客户端实现回调接口实例

    5、修改配置文件

     1 <service name="WCFServer.MyWCFBothway">
     2                 <endpoint address="" binding="wsDualHttpBinding" contract="WCFServer.IMyWCFBothway">
     3                     <identity>
     4                         <dns value="localhost" />
     5                     </identity>
     6                 </endpoint>
     7                 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     8                 <host>
     9                     <baseAddresses>
    10                         <add baseAddress="http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/" />
    11                     </baseAddresses>
    12                 </host>
    13             </service>
    14 </services>



    注:
    1、主要修改使用的方式改为wsDualHttpBinding

    2、http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/ 就为客户端服务引用的链接

    3、本地测试可以使用localhost,如发布服务器需改为服务器IP

    4、端口修改有时会报权限不足,可以将VS用管理员权限打开再编译

    6、启动服务

    1 ServiceHost host1 = new ServiceHost(typeof(WCFServer.MyWCFBothway));
    2 host1.Open();

    二、客户端

    1、引用WCF服务

    通过服务引用引用WCF服务:http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/

    2、实现回调契约接口

    1 [CallbackBehavior(UseSynchronizationContext = false)]
    2     public class MyClientCallBack: IMyWCFBothwayCallback
    3     {
    4         public void ClientCallBack(string msg)
    5         {
    6             Console.WriteLine(msg);
    7             Console.Read();
    8         }
    9     }
    注:
    1、实现的回调接口为IMyWCFBothwayCallback,而不是服务器声明的ICallBack,可以在引用服务后使用对象查看器查看,中间应该是经过代理把名称统一换了
    2、需要声明
    [CallbackBehavior(UseSynchronizationContext = false)],否则回调回失败,感觉像找不到回调函数还是阻塞了就超时了

    3、访问WCF服务

     1 //声明回调实现类实例
     2 MyClientCallBack CallBack = new MyClientCallBack();
     3 //使用回调实现类实例创建会话实例
     4 InstanceContext context = new InstanceContext(CallBack);
     5 //创建WCF服务实例,传入会话实例给服务器是为了方便服务器通过该会话进行回调
     6 WCFBothway.MyWCFBothwayClient W = new MyWCFBothwayClient(context);
     7 //访问WCF服务
     8 string msg = W.DoWork("客户端1");
     9 Console.WriteLine(msg);
    10 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:

     1 <behaviors>
     2             <serviceBehaviors>
     3                 <behavior name="">
     4                     <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
     5                     <serviceDebug includeExceptionDetailInFaults="false" />
     6                 </behavior>
     7             </serviceBehaviors>
     8 </behaviors>
     9 
    10 <service name="WCFServer.WCFNetTcp">
    11                 <endpoint address="" binding="netTcpBinding" contract="WCFServer.IWCFNetTcp">
    12                     <identity>
    13                         <dns value="localhost" />
    14                     </identity>
    15                 </endpoint>
    16                 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
    17                 <host>                  
    18                     <baseAddresses>
    19                         <add baseAddress="net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" />
    20                     </baseAddresses>
    21                 </host>             
    22 </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还是很强大方便的,但是还有很多参数不大清楚,只是使用的默认参数,还需继续去研究。

     

  • 相关阅读:
    java8特性 Optional 工具类
    SpringBoot 配置支付宝接口
    Redis宕机 快速恢复
    flowable流程引擎通过模型ID部署流程
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    Mybatis 动态执行SQL语句
    idea 访问 jsp 404问题
    变量名的命名
    CSS设计 Search窗口
    jQuery实现Ajax功能示例
  • 原文地址:https://www.cnblogs.com/xiaomengshan/p/11175566.html
Copyright © 2020-2023  润新知