1,Dupex(双工) MEP(消息交换模式),服务端回调(Callback)客户端操作

2,客户端调用服务时,附加上一个回调对象(InstanceContext)。服务端处理服务请求时,通过该回调对象调用客户端操作。

3,WCF系统设计常用四层结构:Contracts(契约),Services(服务),Hosting(服务寄宿),Clients(客户端)

4,客户端调用服务,需要服务契约;服务端回调客户端操作,同样需要回调契约。回调契约通过ServiceContract(服务契约)特性的CallbackContract属性指定

5,回调契约本质也是服务契约,但在服务契约里已指明该回调契约的服务契约属性,所以回调契约不需要再标记ServiceContract属性

6,服务端在处理服务请求时,通过当前的OperationContext.Current.GetCallback<T>方法获取回调对象,T代表回调契约的类型

7,OperationContext代表服务操作执行上下文,通过静态属性Current获取当前OperationContent。我们可以在服务端或客户端设置一些上下文,比如为出栈消息添加Soap报头,从入栈消息取出报头等

8,为执行回调,客户端首先要实现回调契约:定义继承回调契约的类,实现回调契约接口方法

9,调用双工服务,先创建回调对象,并通过InstanceContext对回调对象包装,然后用DuplexChannelFactory<TChannel>方法创建服务通道。

10,用服务通道的CreateChannel方法生成服务代理对象,进而调用服务方法。

11,服务响应请求,回调回调对象的方法,在客户端执行回调方法。

契约定义:

using System.ServiceModel;
namespace Contracts
{
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface ICalculator
{
[OperationContract(IsOneWay =true)]
void Add(double x,double y);
} public interface ICallback
{
[OperationContract(IsOneWay = true)]
void DisplayResult(double x, double y, double result);
}
}

服务实现:

using Contracts;
namespace Services
{
public class CalculatorService : ICalculator
{
public void Add(double x, double y)
{
double result = x + y;
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.DisplayResult(x,y, result);
}
}
}

服务寄宿:

using System;
using System.ServiceModel;
using Services;
namespace Hosting
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.Open();
Console.Read();
}
}
}
}

寄宿配置:

  <system.serviceModel>
<services>
<service name="Services.CalculatorService">
<endpoint address="net.tcp://127.0.0.1:9999/CalculatorService" binding="netTcpBinding" contract="Contracts.ICalculator"/>
</service>
</services>
</system.serviceModel>

客户端调用及回调实现:

using Contracts;
using System;
using System.ServiceModel;
namespace Clients
{
class Program
{
static void Main(string[] args)
{
InstanceContext instanceContext = new InstanceContext(new CalculatorCallback());
using (DuplexChannelFactory<ICalculator> ChannelFactory = new DuplexChannelFactory<ICalculator>(instanceContext, "CalculatorService"))
{
ICalculator prox = ChannelFactory.CreateChannel();
using (prox as IDisposable)
{
prox.Add(, );
Console.Read();
}
}
}
}
class CalculatorCallback : ICallback
{
public void DisplayResult(double x, double y, double result)
{
Console.WriteLine($"{x} + {y} = {result}");
}
}
}

客户端配置:

  <system.serviceModel>
<client>
<endpoint name ="CalculatorService" address="net.tcp://127.0.0.1:9999/CalculatorService" binding="netTcpBinding" contract="Contracts.ICalculator"/>
</client>
</system.serviceModel>

WCF Tcp双工通信 Get !

05-11 13:12