WS雙向繫結(Duplex WS Binding):由WSDualHttpBinding類提供,WS雙向繫結與WS綁定相似,但它還支援從服務到用戶端的雙向通訊。雙向繫結的特點是,無論使用單向訊息發送還是請求/回覆訊息發送方式,服務和用戶端均能夠獨立地向對方發送訊息。 對於必須直接與用戶端通訊或向訊息交換的任意一方提供非同步體驗(包括類似於事件的行為)的服務來說,這種雙向繫結形式非常有用。
實現雙向繫結需要做的工作:
A:還必須設計回調協定,並將該回調協定的類型分配給標記服務合約的 ServiceContractAttribute 屬性 (attribute) 的 CallbackContract 屬性(property)。
B:您必須建立第二個介面,該介面包含在用戶端調用的方法聲明。
開發環境:Visual Studio 2010 + Net Framework 4.0 。
下面通過一個DEMO介紹雙向繫結(WSDualHttpBinding)。
1、建立一個WCF Service,主要代碼如下。
介面契約代碼:
[ServiceContract(Namespace = "http://schemas.xinhaijulan.com/demos/DualHttpBinding", CallbackContract = typeof(IHelloWCFServiceCallback))]
public interface IHelloWCFService
{
[OperationContract]
void HelloWCF(string inputMsg);
[OperationContract(IsOneWay = true)]
void HelloWCFOneWay(string inputMsg);
}
public interface IHelloWCFServiceCallback
{
[OperationContract]
void HelloWCFCallback(string msg);
[OperationContract(IsOneWay = true)]
void HelloWCFCallbackOneWay(string msg);
}
注意:上述代碼與前幾章DEMO代碼不同之處為,在ServiceContract標記處添加了CallbackContract = typeof(IHelloWCFServiceCallback),並添加了Callback介面。
實作類別代碼:
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
public class HelloWCFService : IHelloWCFService
{
public void HelloWCF(string inputMsg)
{
IHelloWCFServiceCallback callback = OperationContext.Current.GetCallbackChannel<IHelloWCFServiceCallback>();
callback.HelloWCFCallback(inputMsg);
}
public void HelloWCFOneWay(string inputMsg)
{
IHelloWCFServiceCallback callback = OperationContext.Current.GetCallbackChannel<IHelloWCFServiceCallback>();
callback.HelloWCFCallbackOneWay(inputMsg);
}
}
2、修改設定檔,採用wsDualHttpBinding方式,代碼如下:
<bindings>
<wsDualHttpBinding>
<binding name="dualHttpBinding" transactionFlow="true" maxReceivedMessageSize="100000"
messageEncoding="Text" />
</wsDualHttpBinding>
</bindings>
<services>
<service name="DualBindingServer.HelloWCFService">
<endpoint address="HelloWCF" binding="wsDualHttpBinding" bindingConfiguration="dualHttpBinding"
contract="DualBindingServer.IHelloWCFService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/DualBindingServer/HelloWCFService/" />
</baseAddresses>
</host>
</service>
</services>
3、添加用戶端,並添加Service引用,主要代碼如下:
class Program : DualbindingService.IHelloWCFServiceCallback
{
static void Main(string[] args)
{
Console.WriteLine("Client running on thread {0}" + Environment.NewLine, Thread.CurrentThread.GetHashCode());
Program program = new Program();
InstanceContext instanceContext = new InstanceContext(program);
using (DualbindingService.HelloWCFServiceClient client = new DualbindingService.HelloWCFServiceClient(instanceContext))
{
WSDualHttpBinding binding = client.Endpoint.Binding as WSDualHttpBinding;
binding.ClientBaseAddress = new Uri("http://localhost:8080");
Console.WriteLine("Call HelloWCF Begin");
client.HelloWCF("Hello WCF");
Console.WriteLine("Call HelloWCF End");
Console.WriteLine();
Console.WriteLine("Call HelloWCF OneWay Begin");
client.HelloWCFOneWay("Hello WCF OneWay");
Console.WriteLine("Call HelloWCF OneWay End");
//因使用了OneWay標記屬性的方法:只要調用的方法開始執行,就會繼續執行下面的方法,不會阻塞
//所以,此時如果不使用等待輸入ReadLine()操作,using方法體應付執行結束,那麼client對象也就會close,並釋放
//然而此時Callback方法還並未被執行,因此,若不寫下面的ReadLine(),則在執行Callback方法時,
//會報異常:Additional information: The session was closed before message transfer was complete.。
Console.ReadLine();
}
Console.ReadLine();
}
public void HelloWCFCallback(string msg)
{
Console.WriteLine("HelloWCFCallback on thread {0}, and the message is:{1}", Thread.CurrentThread.GetHashCode(), msg);
}
public void HelloWCFCallbackOneWay(string msg)
{
Console.WriteLine("HelloWCFCallbackOneWay on thread {0}, and the message is:{1}", Thread.CurrentThread.GetHashCode(), msg);
}
}
從以上代碼可以看出,用戶端實現了Callback介面,運行代碼,可以看到如下輸入:
Client running on thread 9
Call HelloWCF Begin
HelloWCFCallback on thread 12, and the message is:Hello WCF
Call HelloWCF End
Call HelloWCF OneWay Begin
Call HelloWCF OneWay End
HelloWCFCallbackOneWay on thread 12, and the message is:Hello WCF OneWay
從輸出可以看出,用戶端運行主線程在thread 9上,而Callback方法運行在thread 12上,說明了Callback為非同步呼叫。
從輸出還可以看出,沒有使用了IsOneWay的方法進行了阻礙,而使用了IsOneWay=true的方法並沒有阻礙,而是繼續執行主線中的方法。然而IsOneWay所起的主要作用是什麼呢?
IsOneWay=true為單向操作,單向操作是用戶端叫用作業並在WCF將訊息寫入網路後繼續進行處理的操作,預設為false。詳細的資訊將在以後的訊息模式篇章中進行介紹。
至此,雙向繫結(WSDualHttpBinding)介紹完畢。
點擊下載DEMO。
作者:心海巨瀾
出處:http://xinhaijulan.cnblogs.com
著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。