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)介绍完毕。
作者:心海巨澜
出处:http://xinhaijulan.cnblogs.com
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。