客户端调用服务方法时附加上一个回调对象,服务端方法执行完后通过回调对象调用客户端中的方法。双方需要定义回调契约,并且客户端需要实现这个回调契约。
先定义两个接口,一个作为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类型,参数传入一个实现了回调契约的实例。