在asp.net中,会话大家应该已经很熟悉,WCF也提供了会话,但是不同的是WCF的会话并没有提供会话的数据缓存共享区域。
其中ServiceContract有个属性,SessionMode,有三个模式:
1、Allowed:指定当传入绑定支持会话时,协定也支持会话
2、Required:指定协定需要会话绑定。如果绑定并未配置为支持会话,则将引发异常。
3、NotAllowed: 指定协定永不支持启动会话的绑定。
其中第二点,之前看了一些博文,解释为:所有调用(即,支持调用的基础消息交换)都必须是同一个对话的一部分。
这种解释其实很难让人明白,MSND的解释已经很明白,会话绑定的协议httpBinding不支持会话,如果配置为比如httpBinding的绑定,那么就会抛异常。
其中,如果配置为TCP,那么,该值必须是Required。
首先来看一下契约的定义,这里做了一个双工的会话,模式为Required。
[ServiceContract(CallbackContract =typeof(ICalculateCallback),SessionMode =SessionMode.Required)]
public interface ICalculate
{
[OperationContract(IsOneWay =true,IsTerminating =true)]
void Add(int a, int b);
[OperationContract(IsOneWay =true,IsInitiating =true)]
void SubStract(int a, int b);
}
这个例子,我们看到除了在服务契约上做了一些会话的定义,在操作上,我们可以看到,Add接口定义了IsTerminating=true,SubStract定义了IsInistating,我们分别来看一下这两个属性的作用。
IsTerminating:获取或设置一个值,该值指示服务操作在发送答复消息(如果存在)后,是否会导致服务器关闭会话。
那么返回值为:如果该操作会导致服务器关闭会话,则为 true;否则为 false。默认值为 false。
这也是这个例子为什么用双工通信来做演示,双工通信做回调处理,如果定义为true,再执行回调处理,那么服务器会话已经关闭,不允许再发送回调消息,如果依然做了回调处理,或者在调用在该服务上定义的操作,就会抛出异常。
IsInitiating:获取或设置一个值,该值指示方法是否实现可在服务器上启动会话(如果存在会话)的操作。
如果允许操作启动服务器上的会话,则为 true;否则为 false。默认值为 true。
回调声明:
public interface ICalculateCallback
{
[OperationContract(IsOneWay =true)]
void Show(int result);
}
下面是客户端定义的服务回调:
public class CalculateCallback : ICalculateCallback
{
public void Show(int result)
{
Console.WriteLine("结果呈现:" + result);
}
}
服务的实现:
public class ServiceCalculator : ICalculate
{
int result = 0;
public void Add(int a, int b)
{
try
{
result += a / b;
//OperationContext.Current.GetCallbackChannel<ICalculateCallback>().Show(result);
}
catch (Exception ex)
{
throw new FaultException<FaultMessage>(new FaultMessage() {
Messgae = ex.Message, Code = 20101
});
}
}
public void SubStract(int a, int b)
{
result+= a - b;
OperationContext.Current.GetCallbackChannel<ICalculateCallback>().Show(result);
}
}
客户端的调用:
static void Main(string[] args)
{
CalculateClient client = new CalculateClient(new InstanceContext(new CalculateCallback()));
client.SubStract(30, 4);
client.Add(100,5);
Console.ReadLine();
}
得到结果是26,这里Add没有执行回调,我们把IsTerminating设置为fasle,Add再执行调用,我们来看一下结果:
我们可以看到result的值执行SubStract得到26,再执行Add计算100/5得到20加上之前得到计算结果26,那么得到了46,在会话调用,期间会保存了上一次调用的结果。