三种交换模式(本链接三种模式的例子):One-Way Calls、Request/Reply、Duplex。
3、Duplex
网上说法不一,有的叫交换模式,有的叫回调模式。反正就是会相互的调用的模式。
服务端:
服务端要定义回调函数,这样才能体现回调
/// <summary>
/// CallbackContract:定义的回调接口
/// </summary>
[ServiceContract(CallbackContract=typeof(ICallback))]
public interface IJob
{
[OperationContract]
string Do(string jobName);
}
服务回调:
[ServiceContract]
public interface ICallback
{
[OperationContract]
void Done(int userTime);
}
服务实现:
服务实现的时候一定要注意ServiceBehavior,否则会报错出现死锁的情况
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class Job : IJob
{
public string Do(string jobName)
{
try
{
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
System.Diagnostics.Stopwatch watcher = new System.Diagnostics.Stopwatch();
watcher.Start();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("服务" + AppDomain.CurrentDomain.FriendlyName + "执行任务:" + jobName);
watcher.Stop();
callback.Done((int)watcher.ElapsedMilliseconds);
return "成功";
}
catch (Exception)
{
return "失败";
}
}
}
寄宿:
static void Main(string[] args)
{
try
{
Uri tcpAddress = new Uri("net.tcp://localhost:6887/Service");
ServiceHost duplexHost = new ServiceHost(typeof(Job), tcpAddress);
oneWayHost.Open();
normalHost.Open();
duplexHost.Open();
Console.WriteLine("服务已启动。。。");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
服务XML:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Service.Job">
<endpoint name="JobService" address="duplex" binding="netTcpBinding" contract="Contract.IJob">
<identity>
<dns value="localHost"></dns>
</identity>
</endpoint>
</service>
</services>
</system.serviceModel>
</configuration>
客户端:
客户端要实现回调,这样才能向服务端返回结果,并且回调也要加上ServiceBehavior。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class MyCallback : ICallback
{
public void Done(int userTime)
{
Console.WriteLine("服务程序已完成,用时{0}毫秒,并且成功调用了回调函数",userTime);
}
}
客户端:
static void Main(string[] args)
{
Console.WriteLine("开始调用。。。");
//初始化一个下文实例,参数是一个回调函数
InstanceContext instanceContext = new InstanceContext(new MyCallback());
//创建双工通道类
using (DuplexChannelFactory<IJob> channelFactory = new DuplexChannelFactory<IJob>(instanceContext, "JobService"))
{
//创建通道
IJob proxy = channelFactory.CreateChannel();
using (proxy as IDisposable)
{
Console.WriteLine(proxy.Do("haha"));
Console.WriteLine("结束调用。。。");
Console.Read();
}
}
}
客户端xml:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding"></binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:6887/Service/duplex" binding="netTcpBinding" bindingConfiguration="netTcpBinding" contract="Contract.IJob" name="JobService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>