前言:
在WCF初探-5:WCF消息交换模式之双工通讯(Duplex)博文中,我讲解了双工通信服务的一个应用场景,即订阅和发布模式,这一篇,我将通过一个消息发送的例子讲解一下WCF客户端如何为双工服务创建回调对象。
双工服务指定一个回调协定,客户端应用程序必须实现该协定以便提供一个该服务能够根据协定要求调用的回调对象。虽然回调对象不是完整的服务(例如,您无法使用回调对象启动一个通道),但是为了实现和配置,这些回调对象可以被视为一种服务。
双工服务的客户端必须:
双工 WCF 客户端对象除了会公开支持回调所必需的功能(包括回调服务的配置)以外,其他的功能和它们的非双工对应项相同。
示例说明:
WCF客户端为双工服务创建回调对象示例:
IMessageExchange.cs的代码如下:
using System.ServiceModel; using System.Collections.Generic; using System.Runtime.Serialization; namespace Service { [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IMessageExchangeCallback))] public interface IMessageExchange { [OperationContract(IsOneWay=true)] void Send(string message); } public interface IMessageExchangeCallback { [OperationContract(IsOneWay = true)] void Receive(string message); } }
MessageExchange.cs的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Service { [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)] public class MessageExchange : IMessageExchange { public void Send(string message) { Console.WriteLine("服务端监听客户端发出的消息:" + message); Callback.Receive(message); } IMessageExchangeCallback Callback { get { return OperationContext.Current.GetCallbackChannel<IMessageExchangeCallback>(); } } } }
注意:回调契约接口IMessageExchangeCallback中的Receive方法是在客户端实现的,所以如果需要在服务端调用回调方法就必须通过当前操作的实例上下文来获取,即上面代码中的Callback对象。
2. Host:控制台应用程序。提供服务寄宿程序,添加对Srevice程序集的引用。完成配置文件和代码就可以承载服务。
Program.cs的代码如下:
logs_code_hide('d4f2e717-54a9-4031-a5e6-f1346c212247',event)" src="/Upload/Images/2015041311/2B1B950FA3DF188F.gif" alt="" />using System; using System.Collections.Generic; using System.Linq; using System.Text; using Service; using System.ServiceModel; namespace Host { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(MessageExchange))) { host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); }; host.Open(); Console.Read(); } } } }View Code
App.config的代码如下:
<?xml version="1.0"?> <configuration> <system.serviceModel> <services> <service name="Service.MessageExchange" behaviorConfiguration="mexBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:1234/MessageExchange/"/> </baseAddresses> </host> <endpoint address="" binding="wsDualHttpBinding" contract="Service.IMessageExchange" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="mexBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>View Code
3. Client:控制台应用程序。客户端程序,启动服务承载程序Host后,添加对服务地址http://localhost:1234/MessageExchange/的引用,将命名空间修改为
MessageExchangeServiceRef,之后在Program.cs完成对双工服务回调接口IMessageExchangeCallback的实现和对服务方法的调用。Program.cs的代码如下:
using System; using Client.MessageExchangeServiceRef; using System.ServiceModel; namespace Client1 { public class CallBackHandler : IMessageExchangeCallback { public void Receive(string message) { Console.WriteLine("客户端监听服务端接收的消息:" + message); } } class Program { static void Main(string[] args) { InstanceContext instanceContext = new InstanceContext(new CallBackHandler()); MessageExchangeClient proxy = new MessageExchangeClient(instanceContext); proxy.Send("Wcf Duplex"); Console.Read(); } } }
运行结果如下:
总结: