一种WCF检测客户端断线方法

来源:互联网 发布:js设置input属性 编辑:程序博客网 时间:2024/05/18 04:56

       一般检测客户端断线重连的方法都是使用心跳检测。然而增加心跳检测将会稍微影响系统的性能,总之这点资源开销的瑕疵对于有强迫症的我来说有点难接受。在WCF里面其实可以实现客户端断线检测,而不需要心跳。

        首先我要声明,这个方法值适用于WCF服务的会话模式。相信一些资深WCF玩家已经猜到我要说的了。下面我来讲解下

1、在基于会话模式的WCF服务中,每一个客户端的连接信道都会有一个ID标示,通过它WCF服务可以甄别不同客户端,从而为每个不同客户端创建一个会话通道。

//这里我们先对契约借口属性进行设置。

         [ServiceContract (CallbackContract = typeof(ICalculatorCallback),SessionMode =SessionMode.Required)]

2、每一个客户端连接的时候。WCF服务都会创建一个InstanceContext实例上下文,它与客户端同生存周期。每一次创建实例上下文的时候,服务类(就是契约借口的实现类)就会被重新创建(准备的说是重新调用其构造函数)实例消亡时候会自动进行垃圾回收。如下代码:

  [ServiceBehavior(InstanceContextMode =InstanceContextMode.PerSession)]       //在类上方添加服务行为,设置为会话模式。

 public class Service1 : IService1,IDisposable                           //继承IDisposable 借口使得在垃圾回收的时候能够调用Dispose函数
    {
        MessageProperties ms;
        RemoteEndpointMessageProperty remp;                           //这两个变量 用来回去客户端的 地址和端口号。
        public Service1()
        {


            //获取远程端口的IP和端口号。 可以利用来进行心跳检测
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId+"构造器被调用");


             ms = OperationContext.Current.IncomingMessageProperties;
             remp = ms[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;


            Console.WriteLine("Get message from " + remp.Address + ":" + remp.Port+"已经连接服务器");

        }


          public void plus(int a, int b)
        {
            //双工通信,调用客户端实现的回调函数。
            ICalculatorCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorCallback>();   
            callback.showResult(a+b,a,b);
        }


        //如果客户端断开连接,会话就会关闭,实例上下文对象会被释放,从而调用这个函数。这时我们就知道客户端已经断开连接了。

            public void Dispose()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId +"Dispose方法被调用");
            Console.WriteLine("Get message from " + remp.Address + ":" + remp.Port + "已经离开服务器");
        }


        ~Service1()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "终止化器被调用");
        }

}

3. 所为这个检测客户端断线的方式就是看会话通道是否关闭,如果客户端断开连接就会关闭会话垃圾回收机制就会释放实例上下文。只要Dispose函数被调用就说明客户端断开连接。所以有关客户端断线的操作在这个函数里面调用或者设置标识就可以了。

4.一些运行结果如下所示。

      

当我禁用本地网络适配器,或者关闭客户端时服务端都能检测到客户端断线并调用Dispose函数 如下



0 0
原创粉丝点击