This website works better with JavaScript
Почетна
Преглед
Помоћ
Регистрација
Пријавите се
torren
/
s_cherry_e
Прати
1
Волим
0
Креирај огранак
0
Датотеке
Дискусије
0
Захтеви за спајање
0
Вики
Дрво:
cf1d2ee40a
Гране
Ознаке
dev
master
s_cherry_e
/
sr
/
nodes
/
gate
/
README.md
README.md
7.5 KB
Историја
Датотека
Gate 节点说明
节点定位
作为外部客户端的统一接入网关,维护长连接与心跳
负责登录鉴权、限速控制、协议白名单校验
根据会话中记录的节点信息,将请求路由到 Game / Map 等后端节点
维护玩家与网关连接的缓存,支持跨节点推送与踢人
启动流程
入口:
gate.go
基于 Cherry 框架配置并启动节点:
ConfigureNode:以 Cluster 模式启动,开启网关特性(第二个参数为 true)
cherryApp.Init:初始化全局应用对象、加载配置
注册组件:
GOPS:运维诊断
配置中心:SDK、ProtoRoute、RateLimiter、Lua
Redis 客户端:GUID、Center
Rate 限速组件
注册 Actor:sessions.NewActor(false)
initApp:设置网关专用的网络解析器(UserActorParser)
Startup:启动网络监听与消息循环
用户解析 Actor(UserActorParser)
文件:
user/actor.go
角色:作为网关上的核心解析器,负责客户端数据流转、心跳、路由与节点同步。
初始化逻辑:
在 OnInit 中注册远程接口:
User_PlayerPush:由后端节点向玩家推送消息
User_PlayerKick:由后端节点控制玩家下线
初始化状态码:预先序列化“重复登录”“未登录”等错误码字节,便于快速踢线
初始化心跳:从配置读取网关心跳超时时间,注册 Heartbeat 包处理
初始化新连接回调:每个新连接创建一个子 Actor(actorAgent)负责该连接的会话与登录
注册数据包路由函数:OnDataRoute,用于处理客户端所有业务消息
初始化节点路由函数:为 Game / Map 等节点注册路由策略
初始化节点同步函数:在 Session 变更或连接关闭时同步到目标 Game / Map 节点
注册网络连接器:当前使用 TCP 监听 cherryApp.App().Address()
会话子 Actor(actorAgent)
文件:
user/actor_agent.go
角色:与单个 pomelo.Agent 一一对应,负责该连接上的登录流程、Session 设置、同步与关闭处理。
核心逻辑:
Login 流程:
校验基础参数与 debug 模式下的 GameNodeID
validateToken:解析并校验登录 token(PID、OpenID、签名等)
从 SDK 配置表中获取渠道信息,校验 PID 合法性
调用 Center 节点(CenterPlayer)根据 PID / OpenID 获取 UID
调用 checkNodeState 确认目标 Game 节点可用(在线人数、维护状态、白名单等)
通过 pomelo.Bind 将 UID 与当前会话绑定,如存在旧会话则踢出
在 Session 中记录 GameNodeID、PID、OpenID 等字段
返回 UserLoginResponse,包含 UID、PID、OpenID、GameNodeID 及扩展参数
SetSession:
根据传入的 StrStrList 动态设置 / 删除 Session 键值
调用 cache.UpdateAgent 刷新玩家在缓存中的映射
遍历需要同步的键,按 key 查找对应 SyncFunc(例如 game / map),推送 Session 到对应节点
OnSessionClose:
从缓存中移除 Agent
调用所有 SyncFunc 执行解绑逻辑(包括 Redis 中的 session 数据)
清理自身引用并退出 Actor
数据路由与限速
OnDataRoute(user/actor.go)
构建 Session 并打印调试日志(可选)
协议路由白名单校验:使用 data.ProtoRoute 限制可访问的路由
限速控制:优先基于 UID,其次基于 IP 调用 rate.Check
登录状态检查:未绑定 UID 且不是 GateUser_Login,则立即踢下线
本地路由:当当前节点类型与目标 route.NodeType 相同时,构造 ChildPath,通过 LocalDataRoute 将请求转发给本节点内部 Actor
远端路由前的检查:
再次确认 Session 已绑定 UID
对除 GameLogin_Enter 外的路由,要求 Session 中已经存在 PlayerID
节点路由:根据 NodeType(Game / Map)获取 routeFunc,完成真正的集群路由
节点路由函数
文件:
user/route.go
Game 节点路由(gameNodeRoute):
从 Session 中获取绑定的 GameNodeID,不存在则踢下线
通过 ClusterLocalDataRoute 将消息发送到对应 Game 节点
Map 节点路由(mapNodeRoute):
仅在角色已进入游戏(GameLogin_Enter)后才能访问
从 Session 中获取 MapNodeID,若为空则返回 NodeMapNodeIDIsEmpty
使用服务发现(Discovery)检查目标 Map 节点是否存在,不存在则返回 NodeMapIsClosed
否则通过 ClusterLocalDataRoute 转发消息
节点状态检查(checkNodeState):
调用目标节点上的 Ops_CheckNodeState,用 UID 与 IP 进行校验
根据返回值或错误决定节点是否可进入,统一映射为 NodeIsClosed / NodeMapIsClosed 等错误码
会话同步(Sessions Sync)
文件:
user/sync.go
sync2Game:
从 Session 中取 GameNodeID 与 PlayerID
当 isBind 为 true:
将 Session 写入 Redis(SendRedisBind)
向 Game 节点的 GateSessions Actor 发送 Sessions_Bind
当 isBind 为 false:
删除 Redis 中的 Session 映射(SendRedisUnbind)
向 Game 节点发送 Sessions_Unbind(携带 PlayerID)
sync2Map:
与 Game 类似,只是目标节点为 Map 节点,并不涉及 Redis 写入
网关缓存(Agent Cache)
文件:
cache/cache.go
数据结构:
playerAgentsMap:playerID → Agent
gameAgentsMap:gameNodeID → {playerID → Agent}
mapAgentsMap:mapNodeID → {playerID → Agent}
UpdateAgent:
根据 Session 中的 PlayerID / GameNodeID / MapNodeID 更新三张映射表
方便后续按玩家、按 Game 节点、按 Map 节点批量推送消息或踢人
RemoveAgent:
在连接关闭时,从上述三张映射表中删除对应记录
推送与踢人
playerPush(user/actor.go)
支持按玩家、按 Game 节点、按 Map 节点三种模式推送:
Player:根据 I64List 中的 playerID 从 playerAgentsMap 中找到 Agent 逐个 Push
GameNode:根据 GameNodeID 找到对应 gameAgentsMap 后遍历 Push
MapNode:根据 MapNodeID 找到对应 mapAgentsMap 后遍历 Push
playerKick(user/actor.go)
可按 FilterNodeIDS 过滤当前 Gate 节点
支持按玩家、按 Game 节点、按 UID、按 Map 节点踢人:
Player:从 playerAgentsMap 中查找并 Kick
GameNode/MapNode:按节点维度批量 Kick
UID:通过 pomelo.GetAgentWithUID 获取 Agent 后 Kick
典型调用流程
登录流程
客户端连接 Gate,网关创建 pomelo.Agent 与 actorAgent
客户端发起登录请求(User_Login,本地路由到 actorAgent.login)
网关校验 token、SDK 配置、获取 UID,检查 Game 节点状态
绑定 UID 与 Session,记录 GameNodeID / PID / OpenID
向客户端返回 UserLoginResponse,同时通过 SetSession / Sync 将会话同步到 Game 节点
业务路由
客户端发送业务协议
OnDataRoute 完成路由白名单、限速、登录状态检查
根据 Session 中记录的 GameNodeID / MapNodeID,将请求路由到对应节点
设计目标
高吞吐:通过轻量级网关、会话分片 Actor 与缓存结构提升并发能力
安全性:统一的 token 验证、协议白名单、限速策略
一致性:通过 Redis + Sessions_Bind/Unbind 保证 Game 节点的会话感知与状态同步
可扩展性:节点路由、同步函数、缓存结构均可扩展新的节点类型或业务需求