local skynet = require "skynet" local snax = require "skynet.snax" local cluster = require "skynet.cluster" local nodename = skynet.getenv("nodeName") local root = {} -- 集群推送 function root.send(node, service, cmd, ...) if not service or not cmd then log.error("node[%s] service[%s] cmd[%s]", node, service, cmd) return end if node == nil or node == "" or nodename == node then -- 本地服务 skynet.send(service, "lua", cmd, ...) else -- 集群服务 cluster.send(node, service, cmd, ...) end end -- 集群请求 function root.call(node, service, cmd, ...) if not service or not cmd then log.error("call node[%s] service[%s] cmd[%s] is nil", tostring(node), tostring(service), tostring(cmd)) return false end if node == nil or 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) end return ok, 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) end return ok, ret1, ret2, ret3, ret4 end end function root.rpsend(node, serv, cmd, ...) if not node or not serv or not cmd then error("rpsend fatal err") end return root.send(node, serv, "redirectS2S", cmd, ...) end function root.rpcall(node, serv, cmd, ...) if not node or not serv or not cmd then error("rpcall fatal err") end return root.call(node, serv, "redirootrectS2S", cmd, ...) end -- 查询节点服务地址 function root.query_node_service_addr(node, name) if is_empty(node) or is_empty(name) then return end 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 --- 请求类型 req 等待返回值 post function root.snaxcall(node, name, address, reqType, func, ...) local bind if node == nil or node == "" or nodename == node then -- 当前节点 bind = snax.queryservice(name) else bind = cluster.snax(node, name, address) end if not reqType or not func then return bind end if reqType == "req" then return bind[reqType][func](...) end bind[reqType][func](...) return nil end -- 向所有agent进行广播 function root.broadcast_game_agent(mdl, cmd, ...) local nodeInfoList = root.get_type_node_list("game") if is_empty(nodeInfoList) then return end for _, v in ipairs(nodeInfoList) do root.send(v.nodeName, ".srvAgentMgr", "broadcast_agents", mdl, cmd, ...) end end -- 广播 function root.broadcast_proto_notify(protoName, msg) if protoName == nil then log.error("广播消息推送失败 protoName[%s]", tostring(protoName)) return false end local nodeInfoList = root.get_type_node_list("gate") if is_empty(nodeInfoList) then return false end for _, v in ipairs(nodeInfoList) do root.send(v.nodeName, ".wsSprotoWatchdog", "s2c_broadcast", protoName, msg) end return true end -- 获取某种类型的所有节点 function root.get_type_node_list(nodeType) local ok, nodes = root.call("master", ".srvNodeMgr", "get_type_node_list", tostring(nodeType)) if not ok or not nodes then return end return nodes end -- 节点信息是否合法 function root.is_node_info_valid(nodeInfo) if nodeInfo == nil then return false end if is_empty(nodeInfo.nodeName) then return false end if nodeInfo.agent == nil and is_empty(nodeInfo.srvName) then return false end return true end -- 发送 - match节点 - 堵塞 function root.call_with_node_info(nodeInfo, cmd, ...) if not root.is_node_info_valid(nodeInfo) then return false end return root.call(nodeInfo.nodeName, nodeInfo.agent or nodeInfo.srvName, cmd, ...) end -- 发送 - match节点 - 非堵塞 function root.send_with_node_info(nodeInfo, cmd, ...) if not root.is_node_info_valid(nodeInfo) then return false end root.send(nodeInfo.nodeName, nodeInfo.agent or nodeInfo.srvName, cmd, ...) end return root