require("utils.StringUtil") require("utils.TableUtil") require "utils.MathUtil" local config = require "robot_config" local skynet = require "skynet" local netpack = require "skynet.netpack" local socketdriver = require "skynet.socketdriver" local deque = require "deque" local string_format = string.format local poold, pooldObj, onlineCount, startId, endId, inpre local factory local queue = {} local fd2serv = {} local id2fd = {} local MSG = {} local id_max function MSG.open( ... ) log("open", ...) end function MSG.close(fd) if fd2serv[fd] and not fd2serv[fd].closing then fd2serv[fd].closing = true skynet.call(fd2serv[fd].agent, "lua", "exit") pcall(skynet.send, poold, "lua", "feed") log(string_format("logout %s", fd2serv[fd].id)) id2fd[fd2serv[fd].id] = nil fd2serv[fd] = nil end end function MSG.error(fd, msg) log("MSG.error", fd, msg) MSG.close(fd) end function MSG.data(fd, msg, sz) if fd2serv[fd] then skynet.redirect(fd2serv[fd].agent, 0, "client", 0, msg, sz) end end local function dispatch_queue() local fd, msg, sz = netpack.pop(queue) if fd then skynet.fork(dispatch_queue) MSG.data(fd, msg, sz) for fd, msg, sz in netpack.pop, queue do MSG.data(fd, msg, sz) end end end MSG.more = dispatch_queue skynet.register_protocol { name = "socket", id = skynet.PTYPE_SOCKET, unpack = function (msg, sz) return netpack.filter(queue, msg, sz) end, dispatch = function (_, _, q, type, ...) queue = q if type then MSG[type](...) end end } skynet.register_protocol { name = "client", id = skynet.PTYPE_CLIENT, } local function add_robot() local time = skynet.time() local robot = factory:pop() local fd = socketdriver.connect(config.host, config.port) socketdriver.start(fd) local id if id_max >= endId then while true do id = math.randomInt(startId, endId) if not id2fd[id] then break end end else id_max = id_max + 1 id = id_max end fd2serv[fd] = {agent = robot, id = id} id2fd[id] = fd pcall(skynet.call, robot, "lua", "start", fd, id, prefix) log(string_format("login %s", fd2serv[fd].id)) -- 定时下线 skynet.timeout(math.randomInt(config.online_time[1], config.online_time[2]) * 100, function() MSG.close(fd) socketdriver.close(fd) end) end local function online() local curCount = 0 for _, _ in pairs(fd2serv) do curCount = curCount + 1 end -- 及时补充人数 if curCount < onlineCount then for i = curCount + 1, onlineCount do add_robot() end end -- log(string_format("online %s", curCount)) skynet.timeout(100, online) end local function start(pooldp, pooldObj, onlineCountp, startIdp, endIdp, inprep) log("start testing ...") factory = deque.clone(pooldObj) poold, onlineCount, startId, endId, inpre = pooldp, onlineCountp, startIdp, endIdp, inprep id_max = startId - 1 for i = 1, onlineCount, inpre do for j = 1, inpre do if i + j - 1 > onlineCount then break end add_robot() end skynet.sleep(100) end -- 每秒检查补充在线人数 online() end skynet.start(function() skynet.dispatch("lua", function (_, _, command, ...) if command == "start" then start(...) return end end) end)