ET消息传输流程

2020-10-26  本文已影响0人  BacteriumFox

ET消息传输流程

结构模型

服务器独占

客户端建立Session

  1. 添加NetOuterComponent

    因为NetOuterComponent外网组件继承自NetworkComponent网络组件,所以在Init类中为Scene添加NetOuterComponent也就等于添加了NetworkComponent,同时NetOuterComponent还指定了网络组件以什么协议沟通;

    • 考虑到服务端Hotfix与Model分离规则,所以NetOuterComponent的事件驱动与组件不在一个类中。
    • NetOuterComponentAwake事件中创建了TService、ProtobufPacker、OuterMessageDispatcher,并保存引用到自身
      • TService:TCPService,继承自AService
      • ProtobufPacker:Protobuf打包器,继承自IMessagePacker,主要用于调用ProtobufHelper对消息进行打包处理
      • OuterMessageDispatcher:外部消息分发组件,继承自IMessageDispatcher,主要用于调用MessageDispatcherComponent对外部消息进行分发处理
  2. 创建Model.Session

    通过外网组件间接调用网络组件的Create方法,先通过TServiceConnectChannel方法传入远端IP地址创建了一个TChannel,然后将TChannel作物初始化参数创建了一个Model.Session,并调用SessionStart方法启动Session。

    • TChannel:TCP通道,继承自:AChannel,在构造函数中创建了Socket、PacketParser,并设置了各种流处理相关属性

      • Socket:套接字
      • PacketParser:包解析器
      • CircularBuffer:缓冲区
    • Session

      在其Awake方法中,将NetworkComponent.Remove自身方法作为委托传入了TChannelErrorCallback中,还将自身的OnRead方法作为委托传入了TChannelReadCallback

      Session的Start方法调用了TChannelStart方法

      1. 建立远程链接

      2. 开始循环异步接收消息

        注意,到这里Model.Session已经创建完成,并且开始接收消息,以下是收到消息后的处理

        • 当一条消息读取完毕后,先调用PacketParser包解析器,进行解包
        • 再通过委托调用SessionOnRead方法对消息进行分发处理
  3. 创建Hotfix.Session

    将上一步生成的Model.Session作为初始化参数,创建一个Hotfix.Session,该类的Dispose方法会自动调用Model.SessionDispose

    在该类的Awake事件中,会给Model.Session添加SessionCallbackComponent热更层Session回调组件;该组件持有两个委托

    • MessageCallback用于Model.Session通过委托调用Hotfix.SessionRun方法
    • DisposeCallback用于Model.Session通过委托调用Hotfix.SessionDispose方法

发送消息

  1. Hotfix.Session

    • 发送消息

      • 发送普通消息,调用Hotfix.SessionSend方法

      • 发送请求消息,调用Hotfix.SessionCall方法,创建一个异步完成的委托回调,用于消息答复时触发ETTask返回

    • 通过OpcodeTypeComponent对应的消息码

    • 调用Model.SessionSend方法

  2. Model.Session

    • 通过NetOuterComponent类的ProtobufPacker序列化消息
    • 写入操作码
    • 调用TChannelSend方法
  3. Tchannel

    • 将消息写入缓冲区CircularBuffer
    • 通过TServiceMarkNeedStartSend方法将自生标记为待发送
    • TServiceUpdate事件将调用TchannelStartSend方法发送消息
    • StartSend调用SendAsync向远端发送一条消息

接收消息

TChannelStart方法将开启循环接收消息。下面演示接收到一条消息后的处理流程

  1. TChannel

    • 当一条消息读取完毕后,先调用PacketParser包解析器,进行解包
    • 通过委托调用SessionOnRead方法对消息进行分发处理
  2. Session

    • 获取操作码

    • 通过OpcodeHelper.IsClientHotfixMessage检测是否是热更层消息

      如果是热更层消息,则通过SessionCallbackComponent委托调用热更层Session处理消息,后续hotfix和Model处理流程是一样的

    • 通过OpcodeTypeComponent操作码-类型组件获取操作码对应的消息类实例

    • 通过NetOuterComponent类的ProtobufPacker反序列化数据

    • 检测消息是否是响应消息

      • 不是响应消息,直接通过NetOuterComponent类的OuterMessageDispatcher调用MessageDispatcherComponent处理消息
      • 是响应消息,通过消息的RpcId查找请求队列中对应的请求,并激活完成事件

服务端Actor模型建立

发送Actor消息

参考服务端MessageHelper(客户端ActorLocation消息参考OperaComponent,服务端参考SessionPlayerComponentSystem

  1. 获取Unit的UnitGateComponentUnit网关组件,并得到组件中网关Session对象的唯一Id

  2. 通过网关Session的唯一Id提取网关服务器设备Id

  3. 通过ActorMessageSenderComponentActor消息发送器管理组件创建一个ActorMessageSenderActor消息发送器,并通过上一步获取的网关服务器设备Id查找到对应的网关服务器的内网地址,赋值到Actor消息发送器中。

  4. 调用Actor消息发送器的Send方法

    使用NetInnerComponent内网组件和网关服务器地址,创建一个链接网关服务器的内网Session,然后使用该Session发送消息。

    由于创建Session时使用的时内网地址,所以会有网关服务器的内网组件接收Session传来的消息,由于内网组件使用的消息分发器和外网组件不同,所以在解析消息的时候Actor消息和普通消息相比会有更多步骤

接收Actor消息

和普通消息前期收取规则是一样的,产生差异在于Session调用消息分发器分发消息时。

对象跨服跳转

参考Actor_TransferHandler

总结

消息分类:

登录流程:

  1. Client建立一个链接Realm的Session
  2. Client向Realm发送登录请求,验证登录账成功后
  3. Realm向Gate获取登录Gate的key和Gate的地址
  4. Realm返回给Client登录Gate的key和Gate的地址
  5. Client通过Gate地址建立一个新的Session,并销毁之前的Session
  6. Client向Gate发送登录Gate请求,验证之前返回Key成功后在Gate创建Player
    1. 将Client地址保存到Player中,方便后续对Client建立Session
    2. 给当前Gate链接Client的Session添加邮箱组件,将Session注册成Actor
  7. Gate返回给Client Player的ID,在客户端建立Player
  8. Client向Gate发送登录Map请求
  9. Gate向Map发送创建Unit请求
  10. Map创建Unit,并返回UnitId
    1. 给Unit添加邮箱组件,注册成Actor
    2. 再调用邮箱组件的AddLocation方法,将Unit注册到Location服务器中
  11. Gate返回给Client在Map返回的UnitId
  12. Client通过UnitId建立Unit
上一篇 下一篇

猜你喜欢

热点阅读