WCF热门问题编程示例(5):WCF服务如何获取客户端在线用户数量?

WCF热门问题编程示例(5):WCF服务如何获取客户端在线用户数量?

这个问题是基于WCF学习交流群的Blood提出的问题,一起讨论了下,做的测试。把相关的讨论,以及测试代码,整理成一篇博文。

【1】问题分析:

     这个问题,在WCF服务编程中也非常的常见,以下是对于这个问题的不同描述形式,但是本质基本类似:

  1. WCF如何获取在线客户端数量?
  2. WCF如何获取在线用户列表?
  3. WCF服务如何知道客户端离线?
  4. 如何判断WCF离线客户端?

    或许还有别的提法,但是基本都是差不多的。

    此类问题出现在回调、双工通信的场景中比较多,有的程序具备类似聊天室的功能,就比较在乎客户端的离线事件。

 

【2】解决办法:

    这里服务端对于客户端在线的判断,也是固定的,基本是基于对通道状态的判断,来实现对于客户端在线状态的判断。

实现的思路基本就是,在服务端维护一个在线客户端Channel的列表List,然后每次通道关闭(Closed)或者出错(Faulted)调用特定的方法来移调通道。

     这里另外一个需要注意的地方就是多线程并发的问题。

    因为在线用户通道list是一个静态变量,多线程访问的时候,需要注意互斥操作的问题。

【3】示例代码:

      这里的代码页比较简单,基本思路:

//回调通道列表,也可以用来保持
private static List<IWCFServiceCallBack> channelsList = new List<IWCFServiceCallBack>();
private  static Object thisLock = new Object();

     另外服务默认的是PerSession实例模式,对于单个客户端Proxy实例只有一个服务。

【3.1】服务端:

     这里最重要的就是一个绑定一个方法给Closed事件,

OperationContext.Current.Channel.Closed += new EventHandler(ShowOffLine);

   全部的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Threading;
//ServiceContract 属性以及 Indigo 使用的所有其他属性均在 System.ServiceModel 命名空间中定义,
//因此本例开头使用 using 语句来引用该命名空间。
namespace WCFService
{
    //1.回调服务契约,由于回调方法在客户端执行,因此无须添加 ServiceContractAttribute。对于回调操作,服务器无须获取其返回信息,因此添加 IsOneWay=true 特性参数。
    public interface IWCFServiceCallBack
    {
        //操作契约
        [OperationContract(IsOneWay=true)]//
        void SayHelloCalllBack();
    }
    //2.服务契约,指定 CallbackContract 回调契约。
    [ServiceContract(CallbackContract = typeof(IWCFServiceCallBack))]
    public interface IWCFService
    {
        //操作契约,
        [OperationContract]
        string SayHelloToUser(string name);

    }
    //3.服务类,继承接口。实现服务契约定义的操作
    public class WCFService : IWCFService
    {
        //回调通道列表,也可以用来保持
        private static List<IWCFServiceCallBack> channelsList = new List<IWCFServiceCallBack>();
        private  static Object thisLock = new Object();

        public WCFService()
        {
            Console.WriteLine("constructed! {0} , …", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        }
        //实现接口定义的方法
        public string SayHelloToUser(string name)
        {
            Console.WriteLine("Begin Call at  {0} , …", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            //获取当前操作客户端对象实例
            IWCFServiceCallBack callback = OperationContext.Current.GetCallbackChannel<IWCFServiceCallBack>();
            //绑定事件方法
            OperationContext.Current.Channel.Closed += new EventHandler(ShowOffLine);
            //OperationContext.Current.Channel.Faulted += new EventHandler(ShowOffLine);
            //添加回调通道
            lock (thisLock)
            {
                channelsList.Add(callback);
            }
            callback.SayHelloCalllBack();
            Console.WriteLine("End Call at {0} , …", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            return "Hello! " + name;
        }

        private void ShowOffLine(object sender, EventArgs e)
        {
            IWCFServiceCallBack callback = sender as IWCFServiceCallBack;
            lock (thisLock)
            {
                channelsList.Remove(callback);
                Console.WriteLine("OffLine! {0} , current clients are {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), channelsList.Count);
            }
        }
    }
}

【3.2】客户端:

      客户端实例化了10个Proxy的实例,调用10次服务,服务回调客户端。我们直接结束客户端的进程,观察一下Host窗口的输出信息。代码很简单,如下:

//CallBack 回调服务
           Console.WriteLine("Call Back Operation Test…");
           for (int i = 0;i < 10;i++)
           {
               IWCFServiceCallback callBack = new WCFServiceCallback();
               InstanceContext context = new InstanceContext(callBack);
               WCFServiceClient WCFServiceCallBackClientProxy = new WCFServiceClient(context, "NetTcpBinding_IWCFService");
               //通过代理调用调用SayHelloToUser,传递对象
               WCFServiceCallBackClientProxy.SayHelloToUser("Frank Xu Lei Call Back");
           }
           //For Debug
           Console.WriteLine("Press any key to continue…");
           Console.Read();

    

【4】运行结果:

       这里我们运行了10个客户端,然后分别关闭10个客户端,可以看到Host窗口打印的在线用户数目在发生变化,依次减少。

HowToGetOnLineClientNum

这里为什么没绑定Faulted 事件上呢?//OperationContext.Current.Channel.Faulted += new EventHandler(ShowOffLine);

而是只保留了对于Closed事件的绑定?

主要原因是,WCF的通道状态机,在通道错误的时候,最后的状态也会转换为CLosed,所以绑定到Closed事件一定会调用我们的ShowOffline方法。

【5】参考文章:

  1. Handling Disconnects with WCFhttp://www.rcs-solutions.com/blog/2008/09/24/HandlingDisconnectsWithWCF.aspx
  2. 线程同步:http://msdn.microsoft.com/zh-cn/library/ms173179(VS.80).aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WCF全面解析(套装上下册)》由蒋金楠所著,是作者多年潜心研究WCF技术的心血之作,也是这些年来从事WCF开发的经验总结。书如其名,此书涵盖了WCF几乎所有的知识点,并对其底层框架进行了“庖丁解牛”式的剖析,力求将WCF的整个运行机制完整而清晰地呈现在读者面前。 《WCF全面解析(套装上下册)》上册的前四章在对WCF进行总体介绍的基础上,对构成终结点的三要素(地址、绑定和契约)进行了系统说明;随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章中采用WCF构建了一个具体的电子商务网站VM,它将指导你如何将理论应用于实践。 《WCF全面解析(套装上下册)》的下册主要涉及一些所谓的“高级”话题,主要包括如何在分布式环境中处理异常(第1章);元数据的导入与导出、发布与获取如何实现(第2章);如何利用WCF对事务的支持将分布式事务引入服务(第3章);如何利用并发与限流机制提高服务的吞吐量和可用性(第4章);如何利用可靠会话机制确保消息的“使命必达”(第5章);如何利用队列服务提供离线通信的支持(第6章);第7、8章主要涉及安全的相关内容,包括传输安全、授权与审核;第9章全景展示WCF服务端和客户端的运行时框架,以及在此基础上的所有扩展可能;最后一章为你带来WCF4.0几个独立的新特性。 编辑推荐 《WCF全面解析(套装上下册)》不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员使用,同样也适合对WCF有一定了解的开发设计人员和架构师阅读。相信不同层次的读者都能从此书中找到自己希望了解的部分。 《WCF全面解析(套装上下册)》的内容不仅适合尚未接触过WCF,希望尽快入门并进行深入研究的开发人员,同样适合对WCF具有一定了解的开发设计人员和架构师。相信不同层次的读者都能从本书中找到自己希望了解的部分。阅读本书的读者需要对.NET,包括对C#和.NET Framework具有一定的了解。如果读者具备了DCOM、Enterprise Library Service、.NET Remoting、Web Service、MSMQ及SOA相关的基础,对阅读此书尽快掌握WCF将大有裨益。 名人推荐我经历了COM时代,一直把Don Box的《COMM本质论》奉为我的指路明灯。能把SOA机理和WCF这种特定厂商实现的技术讲得如《COM本质论》一样完美透彻的,那必属Artech这本经过自己深研、实践而著的心血结晶——《WCF全面解析》。如果你想成为SOA和WCF方面的专家,那么这本书就是你的最好法宝。想想你作为专家而获得的回报,那么你对这本书购买所付出的,简直是太值了。 ——《走出软件作坊》 作者 明源软件CTO 阿朱 首先,金楠是—位工作在一线的优秀的WCF技术人员,这符合我对阅读技术图书的第一个要求和期待。其次,金楠的写作文笔、专业责任也给人以充分信任,这在金楠的文字中读者可以体会。这本《WCF全面解析》全面剖析了构建WCF应用所需要的各方面技术,剥丝抽茧,由浅入深,也是我非常欣赏的技术讲述方式。我相信《WCF全面解析》—书是搞WCF朋友的案头必备。 ——祝成科技与Boolan.com创始人.NET技术专家 李建忠 知识全面、论述准确、逻辑严密是本书的特点。这是一本各层次开发人员都可以从中受益的书:对于初、中级开发人员,它可以帮助你获得WCF全方位的知识,系统地梳理WCF的知识结构,提升动手实践能力;对于高级开发人员,它既可以有效弥补你WCF相关知识中的盲点,又可以让你在自己熟悉的知识点上领略作者的看法和理解。 ——资深架构师 曲春雨 作者简介蒋金楠,网名Artech,现就职于某知名软件公司担任高级软件顾问。连续5届微软MVP(最有价值专家),同时也是少数的双料MVP(Solutions Architecture+Connected System)之一。国内较早接触WCF的人之一,2007年2月起在个人博客(http://www.cnblogs.com/artech)上发表超过两百篇深入介绍WCF的文章,成为了目前国内WCF在线资料的主要来源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值