gaoxiang

专注于.NET技术

博客园 首页 新随笔 联系 订阅 管理
本来Tcp/udp组件是系统与外界交换消息的唯一进出口,而Tcp组件或Udp组件与我们系统唯一的联系是通过消息分派器,如此一来,就相当于ESFramework规定了消息分派器是我们应用与外界交换消息的进出口。这样,才能保证接收到的每个消息和发送出去的每个消息都能被所有的Hook截获。另外,消息分派器需要验证接收到的每个消息格式是否正确、消息是否合法、消息是否符合特定规格等。下面是消息分派器组件和其它各个消息组件之间的联系图:


    消息分派器ITcpStreamDispatcher
定义非常简单:
   
1     public interface ITcpStreamDispatcher
2     {
3         /// <summary>
4         /// DealRequestData 不允许抛出异常        
5         /// </summary>        
6         NetMessage DealRequestData(RoundedMessage reqMsg ,ref bool closeConnection) ;        
7         
8         event CbackRequestRecieved RequestRecieved ;
9     }    

    DealRequestData方法的第一个参数是RoundedMessage类型,这个类从NetMessage继承,如下:

 1     public class RoundedMessage :NetMessage
 2     {
 3         public RoundedMessage(){}
 4 
 5         public RoundedMessage(NetMessage netMsg)
 6         {
 7             this.Header = netMsg.Header ;
 8             this.Body   = netMsg.Body ;
 9             this.Tag    = netMsg.Tag ;
10 
11             this.BodyOffset = netMsg.BodyOffset;
12         }
13 
14         public bool IsFirstMessage = false ;
15         public int  ConnectID      = 0     ; //请求所对应的Tcp连接    
16     }

    相对于NetMessageRoundedMessage包含了更多的信息,ConnectID字段标志了这个消息来自于哪个Tcp连接,分派器有时候需要使用这个标志。
    DealRequestData方法的第二个参数closeConnection表明消息分派器可以控制是否关闭对应的Tcp连接,因为可能存在这样情况,收到了某个消息,当消息分派器在分派这个消息的时候发现这个消息是非法的、或恶意的,则分派器可以通过通知closeConnection参数通知Tcp组件关闭掉对应的连接。
    经常出现这样的情况,消息处理器自己需要直接将消息发送给客户,这就要求了IHookSender的存在:

    public interface IHookSender
    {
        
void HookAndSendNetMessage(int connectID ,NetMessage msg) ;
    }

    通常,消息分派器既要实现ITcpStreamDispatcher接口,又要实现IHookSender接口,因为IHookSender接口在消息分派器中实现是最佳的位置。
    接下来,我们可以看看消息分派器的实现,消息分派器的实现需要引入IContractHelper接口。我们知道,框架是一个“骨架”,而骨架中的细节需要靠具体的应用来填充,IContractHelper就是用来填充这些细节的一个,它提供了关于应用中定义的协议的相关信息,比如,消息头的长度、消息头的标志等等。
   
其定义如下所示:

 1     public interface IContractHelper :IStringEncoder
 2     {
 3         int MessageHeaderLength{get ;} //消息头的长度
 4 
 5         IMessageHeader  ParseMessageHeader(byte[] data ,int offset) ; 
 6 
 7         int ServerType{get ;}//当前服务器的服务器类型(如 cityCode)
 8         
 9         //验证消息头标志
10         bool   ValidateMessageToken(IMessageHeader header) ;
11 
12         NetMessage GetResponseByServiceResultType(NetMessage reqMsg ,int serviceResultType) ;//根据服务失败类型获ServiceResultType取失败回复消息
13                 
14         ServiceType GetServiceType(int serviceKey) ;
15 
16         //验证消息(在CaptureRecievedMsg之后进行),如果失败,将关闭对应的连接
17         bool VerifyFirstMessage(NetMessage msg) ;
18         bool VerifyOtherMessage(NetMessage msg ) ;
19     }
20 
21     #region IStringEncoder
22     /// <summary>
23     /// StringEncoder 限定字符串编码格式
24     /// </summary>
25     public interface IStringEncoder
26     {
27         string GetStrFromStream(byte[] stream ,int offset ,int len) ;
28         byte[] GetBytesFromStr(string ss) ;
29     }
30     #endregion    

    万事具备,消息分派器的实现就水到渠成了。
   

TcpStreamDispatcher

    到现在位置,消息相关的部分大致就这么多,还有一些微小的细节后面会补充进来。读者可能会问,还没有讲到Tcp组件或Udp组件的实现了,关于Tcp组件的介绍,可以参考这篇文章:.NET平台下可复用的Tcp通信层实现 

   接下来的后续文章将讲述基于C/S的4层架构经验。感谢关注!

上一篇:ESFramework介绍之(4)――消息拦截器INetMessageHook

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

posted on 2006-05-18 14:04  S孤单一吻S  阅读(211)  评论(0)    收藏  举报