ESFramework 4.0 快速上手一文中,我们讲述了如何使用Rapid引擎可以快速地上手ESFramework开发,文中介绍了使用ESPlus.Application.CustomizeInfo命名空间下的类可以发送和处理自定义消息,本文我们就通过一个简单的例子来深入讲解如何使用自定义消息。

  例子的场景很简单:假设客户端登陆到服务器之后,要求请求加入某个组,服务端收到该请求后,处理该请求,并给客户端相应的回复 -- 是否加入成功,客户端收到回复后,即可作出相应的处理。

一.定义消息类型和消息协议Contract

  这个场景涉及到两种类型的消息:请求加入组(客户端发给服务器),加入组的结果(服务器回复给客户端)。于是,我们可以定义这两个消息类型:


        public static class InformationTypes
        {
            /// <summary>
            /// 请求加入组 Client =》 Server 。对应的消息体为 JoinGroupContract
            /// </summary>
            public const int JoinGroup = 1;             /// <summary>
            /// 加入组的结果 Server =》 Client 。对应的消息体为 JoinGroupResultContract
            /// </summary>
            public const int JoinGroupResult = 2;
        }

  另外,我们可以客户端发给服务器的请求以及服务器给客户端的回复分别用协议类JoinGroupContract和JoinGroupResultContract封装起来:


        [Serializable]
        public class JoinGroupContract
        {
            public JoinGroupContract() { }
            public JoinGroupContract(string _groupID, string _groupPwd)
            {
                this.groupID = _groupID;
                this.groupPwd = _groupPwd;
            }             #region GroupID
            private string groupID = "";
            /// <summary>
            /// 请求加入组的ID
            /// </summary>
            public string GroupID
            {
                get { return groupID; }
                set { groupID = value; }
            }
            #endregion             #region GroupPwd
            private string groupPwd = "";
            /// <summary>
            /// 请求加入组的密码
            /// </summary>
            public string GroupPwd
            {
                get { return groupPwd; }
                set { groupPwd = value; }
            } 
            #endregion
        }         [Serializable]
        public class JoinGroupResultContract
        {
            public JoinGroupResultContract(){}
            public JoinGroupResultContract(bool _succeed)
            {
                this.succeed = _succeed;
            }             #region Succeed
            private bool succeed = true;
            /// <summary>
            /// 加入组是否成功
            /// </summary>
            public bool Succeed
            {
                get { return succeed; }
                set { succeed = value; }
            } 
            #endregion
        }

  当然,这里的协议类非常简单,而对于我们实际的应用,协议类中封装很多的信息都是可以的。

二.客户端向服务器发送请求

  好了,客户端在引擎初始化成功之后,就可以向服务器发送加入组G001的请求了:

   //向服务器请求 加入G100组
   JoinGroupContract JoinGroupContract = new JoinGroupContract("G100", "123456");
   rapidPassiveEngine.CustomizeInfoOutter.Send(InformationTypes.JoinGroup, ESBasic.Helpers.SerializeHelper.SerializeObject(JoinGroupContract));

三.服务器处理请求,并发送回复给客户端

  服务端通过实现ESPlus.Application.CustomizeInfo.Server.ICustomizeInfoBusinessHandler接口的HandleInformation方法来处理该请求:


        private ICustomizeInfoController customizeInfoController = ......;
        //服务端处理消息
        public void HandleInformation(string sourceUserID, int informationType, byte[] info)
        {
            if(informationType == InformationTypes.JoinGroup)
            {
                JoinGroupContract joinGroupContract = (JoinGroupContract)ESBasic.Helpers.SerializeHelper.DeserializeBytes(info, 0, info.Length);
                string groupID = joinGroupContract.GroupID;  
              
                // ........ (逻辑处理)                 JoinGroupResultContract resContract = new JoinGroupResultContract(true) ;//同意加入
                //向用户发送回复消息
                this.customizeInfoController.Send(sourceUserID, InformationTypes.JoinGroupResult, SerializeHelper.SerializeObject(resContract));
                return;
            }
        }

  

四.客户端处理服务器的回复

  接下来,客户端也可以通过实现ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoBusinessHandler接口的HandleInformationFromServer方法来处理服务器的回复:


        //客户端处理消息
        public void HandleInformationFromServer(int informationType, byte[] info)
        {
            if (informationType == InformationTypes.JoinGroupResult)
            {
                JoinGroupResultContract resContract = (JoinGroupResultContract)SerializeHelper.DeserializeBytes(info, 0, info.Length);
                if (resContract.Succeed)
                {
                    //...... 加入成功了,呵呵
                }
                return;
            }
        }

  这个demo简单地演示了消息类型的定义、协议类的定义、以及客户端向服务器发送请求、服务器处理请求并回复客户端的一个完整的处理流程。通过自定义消息,我们可以在服务端与客户端之间实现非常复杂的协作。所以,哪怕是使用ESFramework的快速引擎,我们也可以做很多很复杂的事情了。

有一点要特别注意,那就是尽可能使消息的尺寸小,在相同的频率下,消息越小,通信的效率越高。在本文的demo中,我们采用的是.NET自带的二进制序列化器将协议对象转化为byte[],而使用这个序列化器,所得到的byte[]通常都非常大,而消息越大,将使得服务端与客户端通信的负担增大。所以,如果有自己更好更简洁的序列化方式,建议不要采用.NET自带的二进制序列化器。

如何使用自定义消息?--ESFramework 4.0 快速上手(04)的更多相关文章

  1. ESFramework 4.0 快速上手(06) -- Rapid引擎(续)

    <ESFramework 4.0 快速上手>系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine.其实,大家 ...

  2. 聊天系统Demo,增加文件传送功能(附源码)-- ESFramework 4.0 快速上手(14)

    本文我们将介绍在ESFramework 4.0 快速上手(08) -- 入门Demo,一个简单的IM系统(附源码)的基础上,增加文件传送的功能.如果不了解如何使用ESFramework提供的文件传送功 ...

  3. 聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)

    在ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码)一文中,我们介绍了使用ESFramework的Rapid引擎开发的winform聊天程序,本文我们将在之前d ...

  4. 离线消息如何实现?-- ESFramework 4.0 快速上手(02)

    在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFrame ...

  5. ESFramework 4.0 快速上手(01) -- Rapid引擎

    (在阅读该文之前,请先阅读 ESFramework 4.0 概述 ,会对本文的理解更有帮助.) ESFramework/ESPlatform 4.0 的终极目标是为百万级的用户同时在线提供支持,因为强 ...

  6. 客户端登录验证 -- ESFramework 4.0 快速上手(15)

    在之前版本的Rapid引擎中,是没有提供客户端登陆验证的机制的,如果要验证用户的帐号密码信息,我们只有自己手动通过自定义信息来实现.在2011.04.25发布的新版本中,客户端Rapid引擎,则内置了 ...

  7. 文件传送,如此简单--ESFramework 4.0 快速上手(13)

    在所有的通信系统中,文件传送是最常见也是最重要的功能之一,ESFramework对文件传送的强大支持也是其亮点之一,使用ESFramework可以非常轻松地实现与文件传送相关的所有需求.ESPlus. ...

  8. 使用紧凑的序列化器,数倍提升性能 —— ESFramework 4.0 快速上手(11)

    在分布式通信系统中,网络传递的是二进制流,而内存中是我们基于对象模型构建的各种各样的对象,当我们需要将一个对象通过网络传递给另一个节点时,首先需要将其序列化为字节流,然后通过网络发送给目标节点,目标节 ...

  9. 监控自定义信息 —— ESFramework 4.0 快速上手(10)

    在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中,我们介绍了通过挂接IMessageSpy到骨架流程,我们就可以监控到所有收发的消息.由于Rapid引擎已经为我们组装 ...

随机推荐

  1. 五大科技巨头VR/AR专利报告,Magic Leap以22.6%领跑

    在十月份发布的<VR/AR专利技术深度分析报告>指出,VR.AR行业的专利多被佳能.索尼.微软.谷歌等科技巨头"包养",但是并没有对这部分进行详细分析.近日,风投公司C ...

  2. iOS开发系列-九宫格算法-xib

    给大家演示 应用程序下载 小项目,效果图:涉及知识点:懒加载,九宫格算法,字典转模型,自定义UIView ,xib文件的使用 首先把素材拖到Xcode项目中:简单看一下素材文件 此时大家应该首先关注. ...

  3. CentOS 7 systemd service开机启动设定

    #vi /etc/systemd/system/xxx.service [Unit] Description=startup script test [Service] Type=simple Exe ...

  4. 在GNU/Linux下将CD音乐转为mp3

    以前我欣赏古典音乐都是听的CD,因而珍藏了不少光盘以及下载到电脑上的ape与flac格式的音乐文件.随着手机硬件性能(如电池续航能力.处理器速度.音质.存储容量等)和软件功能(音乐播放器对于曲目的管理 ...

  5. Java基本知识

    一.I/O 分字节流和字符流 字节流由InputStream和OutputStream读入和写入 DataInputStream继承自FilterInputStream,可以读取基本数据类型(char ...

  6. 【卷二】网络三—UDP服务器与客户端

    这是另一个类型的服务器/客户端,无连接的 UDP: (User Datagram Protocol) 用户数据报协议 参考: P58~P60 UDP 时间戳服务器 [时间戳 就是ctime()显示的内 ...

  7. foreach绑定

    目的 foreach可以将一个数组中的实体循环的进行绑定.这在将一个list显示成table时非常有用. 假设数组是observable的,当在绑定后做了add, remove,或者重新排序后,绑定会 ...

  8. Leetcode - 186 Reverse Words in a String II

    题目: Given an input string, reverse the string word by word. A word is defined as a sequence of non-s ...

  9. Selenium+Python之163邮件发送

    今晚写了一个163邮箱登录的脚本,由于不停的访问163登录主页导致直接访问163邮箱主页登录需要输入验证码,因为无法获取到验证码,就这导致直接访问主页登录脚本不可行,为了绕过验证码,现在先访问hao1 ...

  10. 一种基于FSIM对视频编码图像质量客观评价的方法

    一 为什么对视频编码图像质量客观评价     视频图像质量主观评价一般采用连续双激励质量度量法对任一观测者连续给出原始视频图像和处理过的失真图像,由观测者根据主观感知给出分值,其需针对多个视频对象进行 ...