客户端调用服务方法时附加上一个回调对象,服务端方法执行完后通过回调对象调用客户端中的方法。双方需要定义回调契约,并且客户端需要实现这个回调契约。
先定义两个接口,一个作为WCF类库服务ICalculator接口,另一个回调契约接口ICallback:
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface ICalculator
{
[OperationContract]
void Add(int x, int y);
}
public interface ICallback
{
[OperationContract]
void Dis(int result, int x, int y);
}
ICalculator的服务契约中通过CallbackContract声明回调契约。
对应服务实现为:
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)] public class Cal : ICalculator { public void Add(int x, int y) { ICallback back = OperationContext.Current.GetCallbackChannel<ICallback>(); back.Dis(x + y, x, y); } }
当客户端调用Add方法时,可以通过OperationContext的Current获取当前的回调通道,从而可以调用客户端方法。
服务寄宿使用支持双工通信的netTcpBinding:
static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(kk.Cal)); host.AddServiceEndpoint(typeof(kk.ICalculator), new NetTcpBinding(), "net.tcp://localhost:6666"); host.Opened+=delegate{Console.WriteLine("Service start!");}; host.Open(); Console.ReadLine(); }
客户端代码:
class Program { static void Main(string[] args) { DuplexChannelFactory<kk.ICalculator> fact = new DuplexChannelFactory<kk.ICalculator>(new InstanceContext(new Back()), new NetTcpBinding(), new EndpointAddress(new Uri("net.tcp://localhost:6666"))); kk.ICalculator cal = fact.CreateChannel(); cal.Add(34, 34); } } public class Back : kk.ICallback { public void Dis(int result, int x, int y) { Console.WriteLine("{0}+{1}={2}", x, y, result); } }
通过DuplexChannelFactory<TChannel>获取双工通道工厂,第一个参数为InstanceContext类型,参数传入一个实现了回调契约的实例。