WCF会话 牧羊人

在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,在会话调用,期间会保存了上一次调用的结果。

原文地址:https://www.cnblogs.com/hunter2014/p/5926730.html