WCF消息交换模式之Duplex

时间:2021-02-02 19:43:12
WCF消息交换模式有三种:request/reply,oneWay 和duplex
前两个看看就明白怎么回事。duplex是最复杂的一个,官方文档介绍比较多的一个。
duplex:双方的,相互的意思
duplex格式的契约允许客户端和服务器彼此独立的交流。
duplex是由在客户端和服务器端的两个IsOneWay的契约组成的。
实现方法主要是
在服务器端有两个契约接口:(两个接口都在服务端放置)
一个是由服务端实现来作为服务端类被客户端调用,这就是和前面两个消息交换模式一样的方法。
一个是在客户端实现的接口但被服务端调用的类。
通过这两个接口来实现服务端和客户端的相互交流

简单的代码实现(vs2005 ,控制台应用程序)
服务端代码:
这是两个接口类代码:
&<60;[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required,CallbackContract = typeof(ICalculatorDuplexCallback))]//注意这里面的参数配置
public interface ICalculatorDuplex
 {
 [OperationContract(IsOneWay = true)]
 void Clear();
 [OperationContract(IsOneWay = true)]
 void AddTo(double n);
 [OperationContract(IsOneWay = true)]
void SubtractFrom(double n);
[OperationContract(IsOneWay = true)]
 void MultiplyBy(double n);
 [OperationContract(IsOneWay = true)]
 void DivideBy(double n);
}

 public interface ICalculatorDuplexCallback//这个接口不会在服务器被实现,而是在客户端实现
 {
[OperationContract(IsOneWay = true)]
 void Result(double result);
 [OperationContract(IsOneWay = true)]
void Equation(string eqn);
}
服务端实现的接口
&<60;[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
 public class CalculatorService : ICalculatorDuplex
 {
 double result = 0.0D;
 string equation;

public CalculatorService()
 {
 equation = result.ToString();
 }

 public void Clear()
 {

 Callback.Equation(equation + " = " + result.ToString());
 equation = result.ToString();
 }

 public void AddTo(double n)
 {
 result += n;
 equation += " + " + n.ToString();
 Callback.Result(result);
 }

 public void SubtractFrom(double n)
 {
 result -= n;
 equation += " - " + n.ToString();
 Callback.Result(result);
}

 public void MultiplyBy(double n)
 {
 result *= n;
 equation += " * " + n.ToString();
 Callback.Result(result);
 }

 public void DivideBy(double n)
 {
result /= n;
 equation += " / " + n.ToString();
 Callback.Result(result);
 }

 ICalculatorDuplexCallback Callback//实例接口
 {
 get
 {
 return OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
 }
 }
服务端的配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

 <system.serviceModel>
<services>
 <service
 name="Microsoft.ServiceModel.Samples.CalculatorService"
 behaviorConfiguration="CalculatorServiceBehavior">
 <host>
 <baseAddresses>
 <add baseAddress="http://localhost/servicemodelsamples/service.svc "/>
 </baseAddresses>
 </host>
 <!-- This endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc -->
 <endpoint address=""
 binding="wsDualHttpBinding"
 contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
 <!-- the mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
 <endpoint address="mex"
 binding="mexHttpBinding"
 contract="IMetadataExchange" />
 </service>
 </services>

 <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
 <behaviors>
 <serviceBehaviors>
 <behavior name="CalculatorServiceBehavior">
 <serviceMetadata httpGetEnabled="True"/>
 <serviceDebug includeExceptionDetailInFaults="False" />
 </behavior>
 </serviceBehaviors>
 </behaviors>

 </system.serviceModel>

</configuration>
编译运行,然后svctuil工具生成代码,可以参考上一篇文章。
在客户端代码:
在这个地方实现在服务端的接口
 public class CallbackHandler : ICalculatorDuplexCallback
 {
 public void Result(double result)
 {
 Console.WriteLine("Result({0})", result);
 }

 public void Equation(string eqn)
 {
 Console.WriteLine("Equation({0})", eqn);
 }
 }
main函数的方法:

static void Main()
 {
 // Construct InstanceContext to handle messages on callback interface
 InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

 // Create a client
 CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);

 Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
 Console.WriteLine();

 // Call the AddTo service operation.
 double value = 100.00D;
 client.AddTo(value);

 // Call the SubtractFrom service operation.
 value = 50.00D;
 client.SubtractFrom(value);

 // Call the MultiplyBy service operation.
 value = 17.65D;
 client.MultiplyBy(value);

 // Call the DivideBy service operation.
 value = 2.00D;
 client.DivideBy(value);

 // Complete equation
 client.Clear();

 Console.ReadLine();

 //Closing the client gracefully closes the connection and cleans up resources
 client.Close();
 }
可以参考msdn相关资源

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。