化零为整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
[源码下载]

你可能感兴趣的:(异步调用)