-
全双工的一些细节
-
基于Http协议(wsDualHttpBinding)的全双工回调接口的几个注意点:
-
下面的binding="wsDualHttpBinding"一定要是支持全双工的协议;
<service name="dualService.Dog" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:1709/Design_Time_Addresses/dualService.Dog/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsDualHttpBinding" contract="dualService.IDog"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
-
服务契约一定要加上标注[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(IResult))],这个SessionMode=SessionMode.Required是一直开启会话验证,为此服务设置回调接口(注意:类是不能作为回调的),即CallbackContract=typeof(IResult))。最后一定要为操作契约设置为单项模式,即[OperationContract(IsOneWay=true)]。
[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(IResult))]
public interface IDog
{
[OperationContract(IsOneWay=true)]
void Fly(FlyTarget conposite);
}
[ServiceContract]
public interface IResult
{
[OperationContract(IsOneWay = true)]
void Result(string result);
}
-
在.svc文件中获取当前操作上下文的回调接口的回调管道,即Irslt=OperationContext.Current.GetCallbackChannel<IResult>();,并且使用该接口对象调用该接口中声明的方法,即Irslt.Result("取经失败!")。这里调用接口IResult中的Result方法,实质上是为客户端回调接口的时候,出发这个方法而准备的。
IResult Irslt = null;
public Dog()
{
Irslt = OperationContext.Current.GetCallbackChannel<IResult>();
}
public void Fly(FlyTarget conposite)
{
if(conposite.Magheight>500)
{
Irslt.Result("取经失败!");
}
else
{
Irslt.Result("取经成功!");
}
}
-
最后,在客户端调用服务,并且使用服务调用Fly()方法,这样就可以触发回调接口的方法,然后再客户端在实现服务生成的回调接口IDogCallback即可可完成整个接口回调。
static void Main(string[] args)
{
//using (DogClient dc = new DogClient(new System.ServiceModel.InstanceContext(new Result1())))
//{
DogClient dc = new DogClient(new System.ServiceModel.InstanceContext(new Result1()));
FlyTarget fly = new ServiceReference1.FlyTarget()
{
Magheight = 400
};
dc.Fly(fly);
//}
Console.ReadKey();
}
}
public class Result1:IDogCallback
{
public void Result(string result1)
{
Console.Write(result1);
Console.ReadKey();
}
}
总结,在这个例子中,除开标志服务契约和方法契约为单向模式、服务接口设置为SessionMode=Required以及标志回调接口以外,还要注意要在服务(.svc文件)获取当前操作上下文中的回调接口,然后使用该回调接口的对象调用接口中所需的方法(这里是Result()方法)。最后要在客户端实现服务生成的回调接口即可。