2. 聊天系统 Gate服设计
2.1 设计思路
Gate服务器承担所有客户端连接的入口,专注会话管理、鉴权与多后端路由,把业务逻辑(Chat/Map)和网络协议彻底分离。
- 会话管理:维护
Session生命周期、心跳与断线重连;通过 Flag 组件绑定用户身份。(此篇暂时只专注于Gate与聊天相关的实现) - 路由转发:基于
RouteComponent的 SceneType → UnitRuntimeId 映射,透明转发消息到 Chat 或 Map。 - 统一入口:所有客户端消息仅进 Gate,不直接暴露后端 Chat,实现安全隔离与流量限控。
- 多后端协同:登录时通知 Chat 与 Map 上线、下线时统一广播通知,保证各服状态一致。
这样的设计使后端 Chat/Map 只需关注业务逻辑,无需直接处理网络;Gate 则专注高并发连接与路由中转,可独立横向扩展。
2.2 Gate服主要组件
classDiagram
class GateScene {
+Start()
+OnSessionAccept()
+OnSessionDisconnect()
}
class GateUnitManageComponent {
-Dictionary Units
-Dictionary UnitsByUserName
+Add(userName, session): GateUnit
+Remove(id_or_name)
+ForEachUnitSession(): IEnumerable
}
class GateUnit {
+long Id
+string UserName
+Session Session
+Dictionary Routes
+Dispose()
}
class GateUnitFlagComponent {
+long GateUnitId
}
class RouteComponent {
-Dictionary addressMap
+AddAddress(sceneType, unitRuntimeId)
+Send(toSceneType, message)
+Call(toSceneType, request)
}
GateScene --> GateUnitManageComponent : 挂载
GateScene --> Session : 创建
Session --> GateUnitFlagComponent : 挂载
Session --> RouteComponent : 挂载
GateUnitManageComponent --> GateUnit : 管理
GateUnit --> RouteComponent : 使用Routes
GateScene
方法
Start():启动网络框架OnSessionAccept():新客户端连接,创建Session并挂载 Flag & RouteOnSessionDisconnect():客户端断开,销毁 Flag 触发下线
GateUnitManageComponent
字段
Units/UnitsByUserName:双索引缓存
方法
Add(userName, session):创建或更新GateUnitRemove(id or name):移除并通知多后端ForEachUnitSession():遍历所有有效Session
GateUnit
字段
Id,UserName,SessionRoutes:后端路由字典(SceneType → UnitRuntimeId)
方法
Dispose():释放自身,触发对应的下线通知
GateUnitFlagComponent
字段
GateUnitId:与Session绑定的 GateUnit
RouteComponent
字段
addressMap:SceneType → UnitRuntimeId
方法
AddAddress(sceneType, unitRuntimeId):注册路由Send(toSceneType, message):透明转发消息Call(toSceneType, request):透明发起 RPC
2.3 Gate服上下线流程梳理
客户端发起登录

ClientSession 发送 C2G_LoginRequest 至 GateSession,携带用户名进行鉴权与会话建立。此时进入 Gate服务器处理流程:
GateSession首先进入Gate,然后到达Gate用户管理中心。- 检查用户实体是否在缓存中:
- 若在缓存中,直接从缓存中拿到实体。
- 若不在缓存中,创建实体并添加到缓存中。
- 之后执行登录到其他服务器(如 Chat 服务器、Map 服务器等)的操作 ,在
GateSession上挂载GateUnitFlagComponent(保存 GateUnitId)和RouteComponent(维护后端路由映射);调用GateUnitManageComponent.Add(),将或更新GateUnit实体(包含用户名、Session 引用、路由字典等)到内存缓存;GateSession发起G2Chat_LoginRequest,告知 Chat 服务器该用户上线,并获取ChatRouteId(ChatUnit 的 RunTimeId)等。
客户端下线流程

当客户端发起下线操作时:
ClientSession进入Gate,然后设置延迟卸载。- 触发其他服务器执行下线操作。
- 最后在缓存中移除对应的用户实体。
2.4 Gate服核心流程图
sequenceDiagram
autonumber
participant ClientSession
participant GateSession
participant ChatSession
participant MapSession
ClientSession->>GateSession: 1. C2G_LoginRequest { UserName }
GateSession->>GateSession: 2. 绑定 GateUnitFlagComponent & RouteComponent
GateSession->>GateUnitManageComponent: 3. Add(userName, session)
GateSession->>ChatSession: 4. G2Chat_LoginRequest { UserName, UnitId, GateRouteId }
ChatSession-->>GateSession: 5. Chat2G_LoginResponse { ChatRouteId }
GateSession->>MapSession: 6. G2M_LoginRequest { ChatUnitRouteId }
MapSession-->>GateSession: 7. M2G_LoginResponse { MapRouteId }
GateSession-->>ClientSession: 8. G2C_LoginResponse { ErrorCode=0, ChatRouteId, MapRouteId }
ClientSession->>GateSession: 9. C2Chat_SendMessageRequest { ChatInfoTree }
GateSession->>RouteComponent: 10. route → ChatSession
GateSession->>ChatSession: 11. Other2Chat_ChatMessage { ChatInfoTree }
ChatSession-->>GateSession: 12. Chat2G_ChatMessage or Chat2C_ChatMessage { ChatInfoTree, TargetList? }
GateSession->>GateUnitManageComponent: 13. ForEachUnitSession() or Send to specific GateSessionRunTimeIDs
GateSession-->>ClientSession: 14. Chat2C_Message { ChatInfoTree }
2.5 Gate服核心流程图说明
客户端发起登录
ClientSession发送C2G_LoginRequest至GateSession,携带用户名进行鉴权与会话建立。会话初始化
在GateSession上挂载GateUnitFlagComponent(保存 GateUnitId)和RouteComponent(维护后端路由映射)。注册 GateUnit
调用GateUnitManageComponent.Add(),将或更新GateUnit实体(包含用户名、Session 引用、路由字典等)到内存缓存。向 Chat 服上线
GateSession发起G2Chat_LoginRequest,告知 Chat 服务器该用户上线,并获取ChatRouteId(ChatUnit 的 RunTimeId)。Chat 服返回路由 ID
ChatSession回复Chat2G_LoginResponse,包含ChatRouteId,Gate 将其保存至路由字典。向 Map 服上线
随后GateSession发起G2M_LoginRequest,将ChatRouteId转给 Map 服务器,让 Map 服记录此聊天路由。Map 服返回路由 ID
Map 服务器通过M2G_LoginResponse返回MapRouteId,Gate服更新对应路由映射。Gate 返回登录响应
Gate 汇总所有后端返回的路由信息,发送G2C_LoginResponse给客户端,登录流程完成。客户端发起聊天请求
登录成功后,客户端构造ChatInfoTree并调用C2Chat_SendMessageRequest至 Gate。Gate 路由到 Chat 服
Gate 利用RouteComponent自动将聊天请求转发到指定的ChatSession。Chat 服分发消息
ChatSession根据频道类型(世界、公会、私聊等)通过ChatSceneHelper.Distribution()处理消息,并生成回传消息:- Chat2G_ChatMessage:发送给GateScene的,用于广播到所有客户端(通过 GateUnitManageComponent 遍历所有 GateSession),发送时传入的是具体的目标 GateScene RunTimeID(配置表可以拿)。
- Chat2C_ChatMessage:发送给GateSession的,GateSession会自动转给客户端。用于私聊或定向广播,发送时传入的是具体的目标 GateSession RunTimeID。
Chat 服回传 Gate
Chat 服将处理好的消息(Chat2G_ChatMessage或Chat2C_ChatMessage)发送回 Gate。Gate 分发至客户端
- 对于
Chat2G_ChatMessage,Gate 遍历所有在线 GateSession 并发送; - 对于
Chat2C_ChatMessage,Gate 直接将消息发给列表中指定的 GateSession RunTimeIDs。
- 对于
客户端接收并展示
ClientSession收到Chat2C_Message,解析ChatInfoTree并渲染到 UI。
此流程保证了:
- 单一入口:所有客户端通信均从 Gate 进入,后端无须单独公开端口。
- 双向路由:请求和响应通过同一条路由表透明转发,客户端只需与 Gate 打交道。
- 状态一致:上下线逻辑统一在 Gate 触发,Chat/Map 只聚焦业务分发与回收。
2.6 总结
职责分离
- Gate服:专注连接管理、会话生命周期和透明路由;对外仅暴露单一入口,简化客户端逻辑与监控。
- Chat/Map 服:专注聊天业务与世界逻辑,摆脱网络细节耦合,便于热更新与弹性扩缩。
组件化设计
- FlagComponent:会话→用户映射,实现登录绑定与断线触发下线。
- RouteComponent:维护后端路由表,实现客户端请求与响应的自动双向转发。
- UnitManageComponent:内存中高效管理在线实体,结合超时策略支持延迟销毁与重连容错。
流程流畅
- 登录阶段在 Gate 端完成所有路由注册,后端各负其责;
- 聊天消息全程经由 Gate 转发,Chat 服只需关心消息分发与频道管理;
- 回程同理,保证上下行一致性、简单可靠。
可扩展性与健壮性
- 单 Chat 节点即可承载数万用户;
- 动态添加 Chat/Map 实例时,只需更新路由映射,无需客户端改动;
- 组件化、解藕化的设计使得功能迭代与运维更为便捷。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com