介紹
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