local skynet = require "skynet" local cluster = require "skynet.cluster" local clusterName = skynet.getenv("clusterName") local nodeName = skynet.getenv("nodeName") local root = {} function root:send_to_node(node, service, cmd, ...) if service == nil or cmd == nil then log.error("node[%s] service[%s] cmd[%s]", node, service, cmd) return end if is_empty(node) or nodeName == node then -- 本地服务 skynet.send(service, "lua", cmd, ...) else -- 集群服务 cluster.send(node, service, cmd, ...) end end function root:call_to_node(node, service, cmd, ...) if service == nil or cmd == nil then log.error("call node[%s] service[%s] cmd[%s] is nil", tostring(node), tostring(service), tostring(cmd)) return end if is_empty(node) or nodeName == node then -- 本地服务 local args = {...} local ret1, ret2, ret3, ret4 local ok, msg = xpcall( function() ret1, ret2, ret3, ret4 = skynet.call(service, "lua", cmd, table.unpack(args)) end, debug.traceback ) if not ok then log.error("call failed msg:%s service:%s cmd:%s", msg, tostring(service), cmd) return end return ret1, ret2, ret3, ret4 else -- 集群服务 local args = {...} local ret1, ret2, ret3, ret4 local ok, msg = xpcall( function() ret1, ret2, ret3, ret4 = cluster.call(node, service, cmd, table.unpack(args)) end, debug.traceback ) if not ok then log.error("call failed node:%s service:%s cmd:%s", node, tostring(service), cmd) return end return ret1, ret2, ret3, ret4 end end -- 查询集群节点下服务地址 function root:get_node_service_addr(node, name) local ok, addr = pcall(cluster.query, node, name) if not ok then log.error("Node:%s or srv_name:%s donot exist!!!", node, name) return end return addr end ---------------------------------------- -- 节点分配 ---------------------------------------- -- 分配游戏服节点/agent function root:user_dispatch_game_node_and_agent(uid) local nodeInfo = self:call_to_node("master", ".srvNodeMgr", "user_dispatch_cluster_node", uid, "game") if nodeInfo == nil or is_empty(nodeInfo.nodeName) then return end local gameNode = nodeInfo.nodeName local srvAgentMgr = self:get_node_service_addr(gameNode, ".srvAgentMgr") if srvAgentMgr == nil then return end local agent = self:call_to_node(gameNode, srvAgentMgr, "user_get_game_agent") if agent == nil then return end return gameNode, agent end -- 分配网关节点/agent function root:user_dispatch_gate_node_and_agent(uid) local nodeInfo = self:call_to_node("master", ".srvNodeMgr", "user_dispatch_cluster_node", uid, "gate") if nodeInfo == nil or is_empty(nodeInfo.nodeName) then return end local gameNode = nodeInfo.nodeName local srvAgentMgr = self:get_node_service_addr(gameNode, ".srvAgentMgr") if srvAgentMgr == nil then return end local agent = self:call_to_node(gameNode, srvAgentMgr, "user_get_game_agent") if agent == nil then return end return gameNode, agent end -- 玩家登陆服务器 function root:user_master_band_node(uid, ...) return self:call_to_node("master", ".srvNodeMgr", "user_band_node", clusterName, nodeName, uid, ...) end -- 玩家登出服务器 function root:user_master_unband_node(uid, ...) return self:call_to_node("master", ".srvNodeMgr", "user_unband_node", clusterName, nodeName, uid, ...) end ---------------------------------------- -- 节点调用 - 游戏服 ---------------------------------------- -- agent function root:call_to_game_agent(gameNode, gameAgent, ...) return self:call_to_node(gameNode, gameAgent, ...) end -- send 游戏agent接口处理 function root.sendGameAgentInterface(gameNode, gameAgent, uid, interface, ...) root.send(gameNode, gameAgent, "doCmd", uid, interface, ...) end -- call 游戏agent接口处理 function root.callGameAgentInterface(gameNode, agentAddr, uid, interface, ...) return root.call(gameNode, agentAddr, "doCmd", uid, interface, ...) end -- 获取某种类型的所有节点 function root.get_cluster_node_info_list(nodeType) local ok, nodes = root.call("master", ".srvNodeMgr", "get_cluster_node_info_list", tostring(nodeType)) if not ok or not nodes then return end return nodes end -- 通知业务节点分配服更换节点信息 function root.notifyServerChange(nodeType, nodeList) root.send("ux3_master", ".ux3_server_mgr", "changeServer", nodeType, nodeList) end -- 分配Logic节点 function root.dispatchBattleServer() local ok, server = root.call("ux3_master", ".ux3_server_mgr", "dispatchBattleServer") if not ok then return end return server end -- 通知业务节点分配服进入Battle节点信息 function root.notifyBattleEnter(nodeName) root.send("ux3_master", ".ux3_server_mgr", "battleEnter", nodeName) end -- 通知业务节点分配服离开Battle节点信息 function root.notifyBattleLeave(nodeName) root.send("ux3_master", ".ux3_server_mgr", "battleLeave", nodeName) end return root