zoukankan      html  css  js  c++  java
  • 【转载】ESFramework介绍之(31)―― 消息分类及对应的处理器

    ESFramework介绍之(35)―― IMessageTransceiver

        (本文适用于ESFramework V0.3+)
        
        在ESFramework介绍之(7)-- 服务器代理IServerAgent 一文中,我们详细的介绍了IServerAgent,我们已经知道,客户端与服务器之间的所有通信都可经过IServerAgent,包括要转发的P2P消息。IServerAgent的主要目的是:
    (1)屏蔽客户端与服务端之间的通信协议(Tcp/Udp),ITcpServerAgent、IUdpServerAgent
    (2)可将异步的消息请求/回复转化为同步的方法调用。 

        客户端与服务端的所有交互都可以通过IServerAgent进行,但是如果客户A与客户B之间直接进行P2P通信了?那么A和B之间的P2PMessage就不需要经过服务器转发,即不需要提交给IServerAgent,而是交给IP2PChannel发送;如果客户A和客户B之间不能直接通信,那么A和B之间的P2PMessage就需要经过服务器转发。

        为了对上层应用屏蔽P2PMessage是通过服务器转发器的还是通过IP2PChannel直接发送的,ESFramework引入了IMessageTransceiver,它的智能在于,如果P2PMessage可以通过IP2PChannel直接发送,则将其交给IP2PChannel,否则将其提交给IServerAgent由服务器转发。这样应用只需要直接使用IMessageTransceiver提交(发送)消息就可以了,而不用关心下层的消息路由途径。
        IMessageTransceiver接口定义如下:

        public interface IMessageTransceiver
        {
            
    /// <summary>
            
    /// 如果超时仍然没有回复,则抛出超时异常
            
    /// 如果dataPriority != DataPriority.CanBeDiscarded ,则checkRespond只能为false
            
    /// </summary>     
            NetMessage CommitRequest(NetMessage requestMsg ,DataPriority dataPriority , bool checkRespond);        

            IP2PChannelManager P2PChannelManager{
    set ;}
            IServerAgent ServerAgent{
    set ;}
            IPassiveHelper PassiveHelper{
    set ;}
        }

        IMessageTransceiver及其相关组件关系图如下:
         
          
        我们看到,整个应用所有的消息收发都可以通过IMessageTransceiver进行,而不用在去操作IServerAgent了(当然,我们可以完全在IServerAgent的基础上构建应用,而不关心IMessageTransceiver的存在)。当有消息发送/提交(无论是基本消息、功能请求消息、还是P2P消息)时,直接提交给IMessageTransceiver即可。IMessageTransceiver对要发送的消息采取如下流程:
    (1)如果是非P2P消息,则直接提交给IServerAgent。
    (2)如果是P2P消息,然后向p2PChannelManager查询针对目标客户的P2PChannel是否存在,如果存在,则直接通过P2PChannel发送;否则,就提交给IServerAgent进行转发。
        以下是IMessageTransceiver实现这个流程的代码:

            public NetMessage CommitRequest(NetMessage requestMsg, DataPriority dataPriority, bool checkRespond)
            {
                
    //通过IP2PChannel发送P2PMessage
                if(this.passiveHelper.GetPassiveMessageType(requestMsg.Header.ServiceKey) == PassiveMessageType.P2PMessage)
                {
                    IP2PChannel channel 
    = this.p2PChannelManager.GetP2PChannel(requestMsg.Header.DestUserID) ;
                    
    if(channel != null)
                    {
                        channel.SendMessage(requestMsg) ;
                        
    if(checkRespond)
                        {
                            
    return this.responseManager.PickupResponse(requestMsg.Header.ServiceKey ,requestMsg.Header.CorrelationID) ;
                        }

                        return null ;
                    }
                 }

                return this.serverAgent.CommitRequest(requestMsg ,dataPriority ,checkRespond) ;             
            }

        IP2PChannelManager组件用于管理当前客户与每个其它客户之间的P2P通道,它需要根据服务端发回的其它用户的地址、状态等信息来构建、销毁对应的P2P通道(IP2PChannel)。

        public interface IP2PChannelManager
        {
            IP2PChannel GetP2PChannel(
    string destUserID) ;
        }

        IP2PChannel,如其名,它是客户与客户之间P2P通信的信道的抽象,很显然,目前最常用的P2P通道是基于UDP的NAT穿透的通道,这是IP2PChannelManager的实现之一。如果可能(比如不同的客户位于同一局域网内部),我们也可以在客户之间使用基于Tcp 的P2P通道。IP2PChannel接口定义如下:

        public interface IP2PChannel
        {
            
    void SendMessage(NetMessage msg) ;
        }

       
        现在,使用ESFramework,我们可以在三个层次上构建你的客户端应用:
    (1)直接在NetworkStream或Socket上构建,这样可以完全抛开ESFramework,但是这也需要你自己手动的处理所有麻烦的东西。
    (2)在ITcpServerAgent上构建,这样ESFramework会帮你做好所有消息的收发,请求与回复的匹配,消息的优先级分类、消息的自动发送等等。
    (3)在IMessageTransceiver构建,到这里,你甚至不用关心你的P2P消息是通过P2PChannel直接发送的还是通过服务器进行中转的。底层的通信方式对于你的应用是透明的。

        在后面介绍NAPT穿透时,我会给出基于NAPT的IP2PChannel实现和对应的IMessageTransceiver实现。感谢关注!

  • 相关阅读:
    Optional int parameter 'id' is present but cannot be translated into a null value due to being decla
    Interllij IDEA 使用Git工具
    Interllij IDEA 注释模板(类和方法)
    Intellij IDEA 去掉Mapper文件中的背景
    Interllij IDEA常用快捷键
    JSTL <c:if test=“eq ne lt..”></if> 用法
    启动Tomcat报错 “A child container failed during start”
    服务器证书日期无效 SSL_DATE_INVALID
    window 计算机 开启事务
    MVC Model验证疑难杂症
  • 原文地址:https://www.cnblogs.com/fx2008/p/2265247.html
Copyright © 2011-2022 走看看