ESFramework网络通信框架介绍之(2)――网络通信消息NetMessage

ESFramework网络通信框架与元数据

较之C++而言,.NET是一个更加“动态”的平台,其动态能力建立在反射机制之上,而反射的基础是“元数据”。

    上文已经提到过,如果一个框架要为我们的应用做更多的事情,那么这个框架必须建立更多的标准,必须对框架自己要处理的消息有更多的了解,所以,每个消息都要是自描述的,也就是说每个消息要包含它自己的“元数据”。那么,“元数据”位于消息的何处了?你一定想到了,对,是消息头(MessagHeader)。

    在ESFramework网络通信框架中,消息NetMessage由“消息头+主体”构成,并且消息头和主体都必须实现上文讲到的IContract接口。消息头既是本条NetMessage的元数据,其中包含了诸如消息长度、消息类型等描述信息。ESFramework网络通信框架为了能识别每个消息的元数据,必须再建立一个“标准”,这个标准便是IMessageHeader接口。为了简化后面的计算和应用,ESFramework要求所有的消息头的长度是固定的,比如都是64字节。注意,固定消息头的长度不是必须的,但是这会降低框架的复杂度。
我们来看看IMessageHeader中包含了些什么信息:    

 1     public interface IMessageHeader : IContract ,ICloneable
 2     {
 3         int MessageBodyLength    {get ;set ;} //本消息主体的长度
 4         int TypeKey            {get ;set ;} //请求的服务目录类型
 5         int ServiceKey        {get ;set ;} //请求类型
 6         int ServiceItemIndex{get ;set ;} //请求细分索引
 7         int RandomNum        {get ;set ;} //用于将回复与请求一一对应起来                
 8         int Result            {get ;set ;} //服务结果,1表示成功。其它值对应ServiceResultType            
 9         string DestUserID   {get ;set ;} //接收消息的目标用户编号                
10         string UserID        {get ;set ;} //发出请求的用户编号    
11         bool   P2PAck       {get ;set ;} //仅仅对P2P消息有效,1表示为服务器转发P2P消息的Ack,Result反映了转发成功还是失败。Ack消息主体为null
12         bool   ZipMe        {get ;set ;} //控制对于本条消息是否启用压缩/解压缩,如果有些消息比较短小,则将IMessageHeader.ZipMe设为false
13     }

    IMessageHeader现在已经包含了比较多的内容了,其实刚开始时,IMessageHeader仅仅需要32个字节就足够,随着ESFramework的演化成长,越来越多的信息慢慢加了进来,现在IMessageHeader的长度基本上需要96字节。加进来的内容对很多应用是必须的。

    比如,DestUserID表明了本条消息不是交给服务器处理的,而是要服务器转发给ID为DestUserID的用户,这为框架引入了处理“P2P消息”的能力;有时,用户可能需要发送一系列按顺序的P2P消息,如果是基于UDP,则必须要等到对方确认收到上一个消息后,才可以发送下一个消息,于是就有了P2PAck字段。基于对网络上传输的消息进行压缩是常见的要求,而有些比较短小的消息又不必进行压缩的情况,就出现了ZipMe字段,表明消息是否被压缩/解压过。

    而在你的具体应用中,消息头应该包括哪些内容,由你的应用的需求来决定,比如,你的应用可能从来不需要处理P2P消息,那么在实现IMessageHeader接口时,就不需要关注DestUserID字段和P2PAck字段,并且在你的实际的消息头的字节流中也不需要为它们提供“位置”;而且在使用ESFramework网络通信框架装配你的应用的时候,也不用“接插”“P2PMessage处理器”。这是非常灵活的。

    刚才看到的是消息头的结构,那么消息主体是什么了?在框架这一层,由于框架对所有的具体消息的主体内容一无所知,即使框架知道消息主体可以被解析为一个IContract“对象”,但是在这一层,并没有足够的信息给框架去将主体解析为IContract。所以,框架中的消息主体仍然用字节流byte[]表示,而且框架也根本不关心这个消息主体如何解析、如何处理,这些都是应用的事情。框架已经通过消息的元数据对该消息有足够的了解了。
消息NetMessage的定义如下:

 1     [Serializable]
 2     public class NetMessage
 3     {
 4         public IMessageHeader Header = null ;
 5         public byte[]         Body   = null ; //可以经过压缩、变换Hook
 6         public object         Tag    = null ; //用于在将NetMessage交给IDataDealer时传递额外的信息,不影响ToStream,且很少使用
 7 
 8         public NetMessage()
 9         {
10         }
11 
12         #region Ctor ,ToStream
13         public NetMessage(IMessageHeader header ,byte[] body)
14         {
15              //省略实现......            
23         }
24 
25         public byte[] ToStream()
26         {    
27           //省略实现......            
41         }
42         #endregion
43 
44         #region Length
45         public int Length
46         {
47            //省略实现......            
57         }
58         #endregion
59 
60     }

    Tag字段用于存放可能在后面的消息处理链中需要使用到的额外信息,比如,基于UDP时,Tag可以存放发送本条消息的客户的IPEndPoint,而这个信息可能会被后面的消息处理器用到。
    RoundedMessage包含了比NetMessage更丰富的信息,从网络进口接收到的实际上是RoundedMessage,有时消息分配器或处理器可能需要用到类似ConnectID这样的信息。

    在客户端和应用这一层,NetMessage可以向下转换,因为此时,我们已经知道了消息主体的结构,这个消息主体已经可以被解析为IContract了,所以NetMessage可以转换为Message:  

Message 
    public class Message 
    {
        private IMessageHeader header ;
        private IContract body   ;    

        public Message(IMessageHeader theHeader ,IContract theBody)
        {
            //省略实现......                 
        }    
    
        public NetMessage ToNetMessage()
        {
            //省略实现......            
        }
    
        #region ToStream ,GetStreamLength
        public int GetStreamLength()
        {
            //省略实现......            
        }

        public byte[] ToStream()
        {
            //省略实现......            
        }

        public void ToStream(byte[] buff, int offset)
        {
            //省略实现......                 
        }
        #endregion

        #region Header ,Body ,MessageHelper
        public IMessageHeader Header
        {
           //省略实现......            
        }

        public IContract Body
        {
           //省略实现......            
        }    
        #endregion    
        
    }

    可以看到,

NetMessage已经是一个完全的面向对象的消息了。而至于主体到底含有什么具体的内容,还需要对主体IContract向下转换到具体的协议上才行。这通常是消息处理器的工作。

关于消息处理器和处理器工厂的介绍,请留意下篇文章。 

ESFramework网络通信框架介绍之(3)――消息处理器和处理器工厂 

从2004年7月开始,就一直从事N层C/S架构的服务端的开发,时至今日,慢慢的积累了一些开发经验,ESFramework网络通信框架体系便是这些经验的总结。ESFramework网络通信框架这是一套完全可复用的、灵活的、单纯的、支持N层C/S架构的网络通信框架

上一篇:ESFramework网络通信框架介绍之(1)――网络通信消息协议接口IContract

转到  :ESFramework 可复用的网络通信框架(序)

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 06:21:55

ESFramework网络通信框架介绍之(2)――网络通信消息NetMessage的相关文章

ESFramework网络通信框架介绍之(1)――网络通信消息协议接口IContract

一.ESFramework网络通信框架与字节流        通过网络通信的系统之间(如客户端与服务端的通信)要想正常交互,它们必须有"共同的语言",这种语言就是消息协议.遵守消息协议的消息才能被我们的系统所理解.    我们知道,消息在网路上传输的是字节流,而我们主流的面向对象系统中处理的却是"对象",如何将从网络上接收到的字节流转化为"对象",又如何将"对象"转化为字节流以便通过网络传递给其他系统,这便是IContract

ESFramework网络通信框架介绍之(3)――消息处理器和处理器工厂

一.ESFramework网络通信框架与消息处理器   无论是服务端还是客户端,都需要对接收到的消息进行处理,在ESFramework网络通信框架中,处理消息的组件称为消息处理器,所有的消息处理器都实现了接口IDataDealer:    1     public interface IDataDealer2     {        3         NetMessage  DealRequestMessage(NetMessage reqMsg) ;        4     }    

ESFramework网络通信框架介绍之(5)――消息分派器IMessageDispatcher

  从2004年7月开始,就一直从事N层C/S架构的服务端的开发,时至今日,慢慢的积累了一些开发经验,ESFramework网络通信框架体系便是这些经验的总结.ESFramework网络通信框架这是一套完全可复用的.灵活的.单纯的.支持N层C/S架构的网络通信框架,内置了对Tcp和Udp协议的支持.ESFramework网络通信框架不仅仅提供了一个基础的C/S框架和大量C/S应用中常用的组件,而且在ESFramework网络通信框架框架之上,引入的一个扩展层--ESFramework网络通信框架

ESFramework ——成熟的C#网络通信框架(跨平台)

ESFramework网络通信框架是一套性能卓越.稳定可靠.强大易用的跨平台通信框架.也是.net平台首屈一指的成熟的C#网络通信框架.从最初的单纯的C#网络通信框架,历经10年,已经发展为支持包括安卓.IOS.Xamarin等多个平台的跨平台通信框架.其支持应用服务器集群.其内置了消息的收发与自定义处理(支持同步/异步模型).消息广播.P2P通道.文件传送(支持断点续传).心跳检测.断线重连.登录验证.在线用户管理.好友与群组管理.性能诊断等功能.基于ESFramework,您可以方便快捷地开

网络通信应用开发利器!—— ESPlus —— ESFramework通信框架的增强库

概述 ESPlus 是基于网络通信框架ESFramework通信框架通信框架的增强库.为了更贴近实际应用,加快网络通信系统的开发,ESPlus在ESFramework通信框架原生功能的基础上,进行了再次封装,提供了大多数通信系统中经常用到的组件和功能.在这些功能中,最主要的是:自定义信息.基础API与状态通知.文件传送.P2P框架.好友关系.组关系.Rapid引擎.  1.自定义信息 使用通信框架最基础的需求就是收发信息,ESPlus底层已经为我们封装好了所有与信息收发相关的操作,我们只要调用I

ESFramework网络通信框架 4.0 性能测试

  本实验用于测试ESFramework网络通信框架服务端引擎的性能,测试程序使用ESFramework 4.0版本. 一.准备工作 测试的机器总共有3台,都是普通的PC,一台作为服务器,两台作为客户端. 作为服务器是PC配置如下: 操作系统:Windows Server 2003 Enterprise Edition SP2 CPU:Pentium Dual-Core CPU E5400 @ 2.70GHz 内存:2G   二.测试策略        本实验所采用的策略是这样的: (1)每个客

《Ceph源码分析》——第3章,第1节Ceph网络通信框架

第3章Ceph网络通信本章介绍Ceph网络通信模块,这是客户端和服务器通信的底层模块,用来在客户端和服务器之间接收和发送请求.其实现功能比较清晰,是一个相对较独立的模块,理解起来比较容易,所以首先介绍它. 3.1 Ceph网络通信框架一个分布式存储系统需要一个稳定的底层网络通信模块,用于各节点之间的互联互通.对于一个网络通信系统,要求如下:高性能.性能评价的两个指标:带宽和延迟.稳定可靠.数据不丢包,在网络中断时,实现重连等异常处理.网络通信模块的实现在源代码src/msg的目录下,其首先定义了

ESFramework 通信框架安全机制的设计与实现

      在分布式通信系统中,安全无疑是非常重要的.ESFramework通信框架提供了哪些安全保障了?由于ESFramework通信框架是应用层的开发框架,那么本文我们只讨论ESFramework通信框架在应用层涉及到的安全问题.如果黑客是在网络层或链路层进行攻击,位于应用层的系统是无能为力的.从应用层来说,安全的重要性主要体现在以下几个方面:(1) 防止恶意用户使用格式不正确的消息来试探服务端.(2) 防止通信的消息被恶意用户截获,或者,即使被恶意用户截获,也无法破解其内容.(3) 防止恶

可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)

      (本文所介绍的新功能位于2011.04.18发布的最新版本中,此次版本变更请参见ESFramework通信框架通信框架 4.0 版本升级说明(持续更新))       使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了,那么,如何得知接收方是否已经收到了我们发出的信息了呢?特别是针对一些非常重要的信息,确认对方已经收到是非常重要的.ICu