化零为整WCF(6) - 消息处理(异步调用OneWay, 双向通讯Duplex)

简介:
[索引页]
[源码下载] 


化零为整WCF(6) - 消息处理(异步调用OneWay, 双向通讯Duplex)


作者: webabcd


介绍
WCF(Windows Communication Foundation) - 消息处理:通过操作契约的IsOneWay参数实现异步调用,基于Http, TCP, Named Pipe, MSMQ的双向通讯。


示例(异步调用OneWay)
1、服务
IOneWay.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.Message 

      /// <summary> 
         /// IOneWay接口 
         /// </summary> 
        [ServiceContract] 
         public  interface IOneWay 
        { 
                 /// <summary> 
                 /// 不使用OneWay(同步调用) 
                 /// </summary> 
                [OperationContract] 
                 void WithoutOneWay(); 
 
                 /// <summary> 
                 /// 使用OneWay(异步调用) 
                 /// </summary> 
                [OperationContract(IsOneWay= true)] 
                 void WithOneWay(); 
        } 
}
 
OneWay.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.Message 

         /// <summary> 
         /// OneWay类 
         /// </summary> 
         public  class OneWay : IOneWay 
        { 
                 /// <summary> 
                 /// 不使用OneWay(同步调用) 
                 /// 抛出Exception异常 
                 /// </summary> 
                 public  void WithoutOneWay() 
                { 
                         throw  new System.Exception( "抛出Exception异常"); 
                } 
 
                 /// <summary> 
                 /// 使用OneWay(异步调用) 
                 /// 抛出Exception异常 
                 /// </summary> 
                 public  void WithOneWay() 
                { 
                         throw  new System.Exception( "抛出Exception异常"); 
                } 
        } 
}
 
 
2、宿主
OneWay.cs
using (ServiceHost host =  new ServiceHost( typeof(WCF.ServiceLib.Message.OneWay))) 

        host.Open(); 
 
        Console.WriteLine( "服务已启动(WCF.ServiceLib.Message.OneWay)"); 
        Console.WriteLine( "按<ENTER>停止服务"); 
        Console.ReadLine(); 
 
}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
        <services> 
            <!--name - 提供服务的类名--> 
            <!--behaviorConfiguration - 指定相关的行为配置--> 
            <service name="WCF.ServiceLib.Message.OneWay" behaviorConfiguration="MessageBehavior"> 
                <!--address - 服务地址--> 
                <!--binding - 通信方式--> 
                <!--contract - 服务契约--> 
                <endpoint address="" binding="basicHttpBinding" contract="WCF.ServiceLib.Message.IOneWay" /> 
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
                <host> 
                    <baseAddresses> 
                        <add baseAddress="http://localhost:12345/Message/OneWay/"/> 
                    </baseAddresses> 
                </host> 
            </service> 
        </services> 
        <behaviors> 
            <serviceBehaviors> 
                <behavior name="MessageBehavior"> 
                    <!--httpGetEnabled - 使用get方式提供服务--> 
                    <serviceMetadata httpGetEnabled="true" /> 
                    <serviceDebug includeExceptionDetailInFaults="true"/> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 
    </system.serviceModel> 
</configuration>
 
3、客户端
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.Windows.Forms; 
using System.ServiceModel; 
 
namespace Client2.Message 

         /// <summary> 
         /// 演示Message.OneWay的类 
         /// </summary> 
         public  class OneWay 
        { 
                 /// <summary> 
                 /// 调用IsOneWay=true的操作契约(异步操作) 
                 /// </summary> 
                 public  void HelloWithOneWay() 
                { 
                         try 
                        { 
                                var proxy =  new MessageSvc.OneWay.OneWayClient(); 
 
                                proxy.WithOneWay(); 
 
                                proxy.Close(); 
                        } 
                         catch (Exception ex) 
                        { 
                                MessageBox.Show(ex.ToString()); 
                        } 
                } 
 
                 /// <summary> 
                 /// 调用IsOneWay=false的操作契约(同步操作) 
                 /// </summary> 
                 public  void HelloWithoutOneWay() 
                { 
                         try 
                        { 
                                var proxy =  new MessageSvc.OneWay.OneWayClient(); 
 
                                proxy.WithoutOneWay(); 
 
                                proxy.Close(); 
                        } 
                         catch (Exception ex) 
                        { 
                                MessageBox.Show(ex.ToString()); 
                        } 
                } 
        } 
}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
        <client> 
            <!--address - 服务地址--> 
            <!--binding - 通信方式--> 
            <!--contract - 服务契约--> 
            <endpoint address="http://localhost:12345/Message/OneWay/" binding="basicHttpBinding" contract="MessageSvc.OneWay.IOneWay" /> 
        </client> 
    </system.serviceModel> 
</configuration>
 
 
运行结果:
单击"btnWithOneWay"按钮,没有弹出提示框。(异步操作)
单击"btnWithoutOneWay"按钮,弹出错误提示框。(同步操作)



示例(双向通讯Duplex)
1、服务
IDuplex.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.Message 

         /// <summary> 
         /// IDuplex接口 
         /// </summary> 
         /// <remarks> 
        /// CallbackContract - 回调接口 
        /// </remarks> 

        [ServiceContract(CallbackContract =  typeof(IDuplexCallback))] 
         public  interface IDuplex 
        { 
                 /// <summary> 
                 /// Hello 
                 /// </summary> 
                 /// <param name="name">名字</param> 
                [OperationContract(IsOneWay =  true)] 
                 void HelloDuplex( string name); 
        } 
 
         /// <summary> 
         /// IDuplex回调接口 
         /// </summary> 
         public  interface IDuplexCallback 
        { 
                 /// <summary> 
                 /// Hello 
                 /// </summary> 
                 /// <param name="name"></param> 
                [OperationContract(IsOneWay =  true)] 
                 void HelloDuplexCallback( string name); 
        } 
}
 
Duplex.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.Message 

         /// <summary> 
         /// Duplex类 
         /// </summary> 
         public  class Duplex : IDuplex 
        { 
                 /// <summary> 
                 /// Hello 
                 /// </summary> 
                 /// <param name="name">名字</param> 
                 public  void HelloDuplex( string name) 
                { 
                         // 声明回调接口 
                        IDuplexCallback callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>(); 
                         
                         // 调用回调接口中的方法 
                        callback.HelloDuplexCallback(name); 
                } 
        } 
}
 
 

2、 宿主
Duplex.cs
using (ServiceHost host =  new ServiceHost( typeof(WCF.ServiceLib.Message.Duplex))) 

        host.Open(); 
 
        Console.WriteLine( "服务已启动(WCF.ServiceLib.Message.Duplex)"); 
        Console.WriteLine( "按<ENTER>停止服务"); 
        Console.ReadLine(); 
 
}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
        <services> 
            <!--name - 提供服务的类名--> 
            <!--behaviorConfiguration - 指定相关的行为配置--> 
            <service name="WCF.ServiceLib.Message.Duplex" behaviorConfiguration="MessageBehavior"> 
                <!--address - 服务地址--> 
                <!--binding - 通信方式--> 
                <!--contract - 服务契约--> 
                <!--双向通讯可以基于Http, TCP, Named Pipe, MSMQ;其中基于Http的双向通讯会创建两个信道(Channel),即需要创建两个http连接--> 
                <!--endpoint address="Message/Duplex" binding="wsDualHttpBinding" contract="WCF.ServiceLib.Message.IDuplex" /--> 
                <endpoint address="Message/Duplex" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IDuplex" /> 
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
                <host> 
                    <baseAddresses> 
                        <add baseAddress="http://localhost:12345/Message/Duplex"/> 
                        <add baseAddress="net.tcp://localhost:54321/"/> 
                    </baseAddresses> 
                </host> 
            </service> 
        </services> 
        <behaviors> 
            <serviceBehaviors> 
                <behavior name="MessageBehavior"> 
                    <!--httpGetEnabled - 使用get方式提供服务--> 
                    <serviceMetadata httpGetEnabled="true" /> 
                    <serviceDebug includeExceptionDetailInFaults="true"/> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 
    </system.serviceModel> 
</configuration>
 
 

3、客户端
Duplex.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
using System.Windows.Forms; 
 
namespace Client2.Message 

         /// <summary> 
         /// 演示Message.Duplex的类 
         /// </summary> 
         public  class Duplex 
        { 
                 /// <summary> 
                 /// Hello 
                 /// </summary> 
                 /// <param name="name">名字</param> 
                 public  void HelloDulex( string name) 
                { 
                        var ct =  new Client2.Message.CallbackType(); 
                        var ctx =  new InstanceContext(ct); 
 
                        var proxy =  new MessageSvc.Duplex.DuplexClient(ctx); 
 
                        proxy.HelloDuplex(name); 
                } 
        } 
}
 
CallbackType.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.Windows.Forms; 
 
namespace Client2.Message 

         /// <summary> 
         /// 实现回调接口 
         /// </summary> 
         public  class CallbackType : MessageSvc.Duplex.IDuplexCallback 
        { 
                 /// <summary> 
                 /// Hello 
                 /// </summary> 
                 /// <param name="name">名字</param> 
                 public  void HelloDuplexCallback( string name) 
                { 
                        MessageBox.Show( "Hello: " + name); 
                } 
        } 
}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
        <client> 
            <!--address - 服务地址--> 
            <!--binding - 通信方式--> 
            <!--contract - 服务契约--> 
            <!--endpoint address="http://localhost:12345/Message/Duplex/" binding="wsDualHttpBinding" contract="MessageSvc.Duplex.IDuplex" /--> 
            <endpoint address="net.tcp://localhost:54321/Message/Duplex" binding="netTcpBinding" contract="MessageSvc.Duplex.IDuplex" /> 
        </client> 
    </system.serviceModel> 
</configuration>
 
 

运行结果:
单击"btnDuplex"按钮后弹出提示框显示"Hello: webabcd"


OK
[源码下载]





     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/344116 ,如需转载请自行联系原作者
相关文章
wcf双工通讯
首先说一个服务引用不成功的解决办法: 需要把服务端配置文件中的Binding换成: 或: 下面是一个wcf的简单示例: 服务契约代码: using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace WcfService { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IUser”。
999 0
|
监控 NoSQL
Wcf通讯基础框架方案(一)——基本结构
由于希望使用Wcf作为公司内的通讯框架,因此基于Wcf进行了一些扩展,主要的目的有以下几个方面: 1) 希望减少客户端调用的复杂度,调用方式简化为WcfServiceLocator.Create().Add(1,2)。
795 0