1.聊天系统架构设计总览

  1. 1.聊天系统架构设计总览
    1. 1.1 知识点
      1. 需求分析
      2. 设计思路
      3. 架构图概览
      4. 核心模块职责
        1. 客户端
        2. Gate 服务器
        3. Chat 服务器
        4. Map/Game 服务器
      5. 总结

1.聊天系统架构设计总览


1.1 知识点

需求分析

聊天系统在实际游戏中,会遇到各种功能和性能需求,包括但不限于:

  • 地图聊天
    向同一个场景/地图中的所有玩家广播消息,需优化广播性能与服务器负载。
  • 世界广播
    向全服玩家发送重要公告或活动信息,优先级管理与实时推送至关重要。
  • 私聊
    一对一安全私密通信,需对接收方在线状态进行校验并支持双向回显。
  • 群组聊天
    支持队伍、公会、临时群组等多种群聊,涉及权限控制、成员管理与离线消息补发。
  • 系统消息
    道具变更、战斗记录等系统通知,结合事件驱动与消息队列实现可靠下发。
  • 广播系统
    跑马灯、滚动公告、大喇叭、置顶消息等多样化播报形式,需设计优先级排序和频道管理。
  • 自定义消息
    表情、装备信息、动图、超链接、语音、游戏功能链接等富媒体内容支持,要求灵活拓展与兼容。
  • 聊天节点事件
    点击链接打开界面、跳转到地图、使用物品等互动事件,需事件驱动模型与易维护的解析机制。
  • 高并发与限速
    多人同时发言、刷屏控制、聊天 CD、敏感词过滤、黑白名单等防护与限流策略。
  • 可扩展性
    多 Chat 服集群、动态路由、热更新、离线消息存储与拉取能力。
  • 离线聊天
    使用数据库存储离线聊天消息,用户上线时拉取。

设计思路

聊天系统需要在高并发低延迟可扩展的前提下,支持地图聊天、世界广播、私聊、群组、系统消息等多种场景。总体上,我们采用了分层设计

  1. 客户端负责 UI、协议封包与解包、心跳维护等基础能力。
  2. Gate 服务器负责路由、会话管理以及向后端服务器(Chat/Map)中转聊天协议。(Gate部分详看注册登录,这里只讨论专注于聊天的实现)
  3. Chat 服务器作为聊天中枢,管理在线聊天单元(ChatUnit)、频道(ChatChannel)、聊天消息包解析与分发;并对外提供路由接口供 Gate 和其他服调用。
  4. Map/Game 服务器在收到游戏逻辑触发的系统或世界广播时,通过内网路由将消息推送至 Chat,再由 Chat 分发;或直接将 Chat 消息下发给指定客户端。

这种分层将业务逻辑(聊天分发、频道管理)和网络路由(Gate 中转、RouteComponent 自动转发)解耦,使系统具备灵活扩展多 Chat 节点、支持动态热更、并能在单 Chat 服承载数万在线玩家的场景下依然保持稳定。

注意:所有客户端 ↔ 后端通信均通过 Gate,Chat 与 Map 发回客户端也借助 Gate 转发,保证通道一致、监控可控。

架构图概览

graph LR
  subgraph 客户端
    direction TB
    ChatClientScene["ChatClientScene"]
    Serializer["SerializerComponent"]
    ClientSession["ClientSession"]
    ChatClientScene -->|"挂载"| Serializer
    ChatClientScene -->|"创建"| ClientSession
  end

  subgraph Gate服
    direction TB
    GateScene["GateScene"]
    GateUnitManage["GateUnitManageComponent"]
    GateSession["GateSession"]
    GateFlag["GateUnitFlagComponent"]
    GateUnit["GateUnit"]
    RouteComp["RouteComponent"]
    GateScene -->|"挂载"| GateUnitManage
    GateScene -->|"创建"| GateSession
    GateSession -->|"挂载"| GateFlag
    GateSession -->|"绑定路由"| RouteComp
    GateSession -->|"关联"| GateUnit
    GateUnitManage -->|"管理"| GateUnit
  end

  subgraph Chat服
    direction TB
    ChatScene["ChatScene"]
    Serializer2["SerializerComponent"]
    ChatUnitManage["ChatUnitManageComponent"]
    ChatSession["ChatSession"]
    ChatUnit["ChatUnit"]
    ChatChannelCenter["ChatChannelCenterComponent"]
    ChatChannel["ChatChannel"]
    ChatRouteId["ChatRouteId"]
    ChatScene -->|"挂载"| Serializer2
    ChatScene -->|"挂载"| ChatUnitManage
    ChatScene -->|"挂载"| ChatChannelCenter
    ChatScene -->|"创建"| ChatSession
    ChatSession -->|"注册路由 ChatUnitRuntimeId 返回给 Gate"| ChatRouteId
    ChatChannelCenter -->|"申请/解散"| ChatChannel
    ChatChannel -->|"Unit 字典"| ChatUnit
    ChatUnitManage -->|"管理"| ChatUnit
    ChatUnit -->|"Channel 字典"| ChatChannel
  end

  subgraph Map服
    direction TB
    MapScene["MapScene"]
    MapSession["MapSession"]
    MapRouteId["MapRouteId"]
    MapScene -->|"创建"| MapSession
    MapSession -->|"注册路由 MapUnitRuntimeId 返回给 Gate"| MapRouteId
    MapSession -->|"Other2Chat_ChatMessage"| ChatSession
  end

  %% 消息流
  ClientSession -->|"C2Chat_SendMessageRequest"| GateSession
  GateSession -->|"Route → Chat (via RouteComponent)"| ChatSession
  GateSession -->|"Route → Map (via RouteComponent) (上线时 Map 记录 ChatUnitRouteId)"| MapSession
  ChatChannel -->|"innerRoute(Chat2C_Message)"| GateSession
  GateSession -->|"Route back to Client"| ClientSession

核心模块职责

客户端

  • 构造 ChatInfoTree(一个聊天消息包),逐步添加 ChatInfoNode (聊天信息节点)后发生聊天消息包。
  • 一个 ChatInfoTree 包括多个 ChatInfoNodeChatInfoNode 有不同类型,包括文本、位置、链接,图片,标签等。
  • 聊天相关的信息,如枚举,ChatInfoTreeChatInfoNode应该是和双端一致的。另一端主要是聊天服使用。
  • 客户端和服务端都添加SerializerComponent对聊天消息进行序列化和反序列化。
  • 通过 KCP/TCP 将 C2Chat_SendMessageRequest 发给 Gate。Gate会进行路由。
  • 解析 Chat2C_Message,收到消息后解析ChatInfoTree,再在客户端进行处理。

Gate 服务器

  • GateUnitManageComponent:内存缓存所有在线用户的 GateUnit。
  • GateUnit:一个Gate用户,包括用户名,关联的Session,路由字典等。路由字典的key是服务器类型,值是对应服务器Unit。方便下线时发消息通知其他服务器Unit下线。
  • GateUnitFlagComponent:会话绑定,让Session直接可以知道对应的GateUnitId,断开Session触发下线逻辑时直接可以基于GateUnitId通知GateUnitManageComponent。
  • RouteComponent:自动将客户端请求路由到 Chat 或 Map,并把后端响应转回客户端。会维护一个路由字典,类型是SceneType->其他服的Unit的RunTimeID。这样方便直接找到对应的Unit进行通信。注意Id是最好各个服的Unit保持一致,RunTimeId是用于通信的。

Chat 服务器

  • ChatUnitManageComponent:管理 ChatUnit(用户在 Chat 服的身份与路由 ID)。
  • ChatUnit:管理 ChatUnit(用户在 Chat 服的身份与路由 ID)。存储GateRouteId(Gate的session.RunTimeId)方便发消息时路由。还包括ChannelDict存储假如的Channel。还可以拓展存储发送消息的时间避免频繁发送消息。
  • ChatChannelCenterComponent:申请/销毁频道(世界、队伍、公会、地图等)。使用字典管理ChatChannel。
  • ChatChannel:频道内成员列表、广播消息实现。
  • ChatSceneHelper:核心分发 Distribution(chatUnit, tree),按频道类型调用 Broadcast,Channel,Private 等。核心思路就是找对应的ChatUnit的GateRouteId发给Gate,Gate再转给客户端。

Map/Game 服务器

  • 上线时,Gate的会发送chatUnitRouteId(chatUnit.RunTimeId)给Map记住,这样战斗服想聊天时也可以聊天。
  • 处理游戏触发的系统广播或世界聊天,使用 ChatHelper.SendChatMessage(scene, chatUnitRouteId, tree) 推送至 Chat,Chat转给Gate,Gate再转客户端。

总结

  • 分层解耦:客户端、Gate、Chat、Map 各司其职,逻辑清晰、易维护。
  • 路由中转:Gate 通过 RouteComponent 做透明转发,Chat 侧只关注业务分发。
  • 内存管理:GateUnit/ChatUnit 缓存结合超时组件,实现延迟下线与热重载友好。
  • 消息树协议:双端共享的 ChatInfoTree、ChatNodeFactory、ChatNodeEventHelper,保证一致性与灵活扩展。
  • 拓展和展望:暂时没有做离线聊天,离线聊天需要数据库支持,才能让好友上线时收到消息,并且成本会加

后续将深入拆解 Gate 服设计、消息包(消息树)设计、Chat 服核心逻辑与其他服触发场景。



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏