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 string_format = string.format local queue = {} local fd2serv = {} local id2fd = {} local MSG = {} local id_max = 0 -- robot id function MSG.open( ... ) print("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") log(string_format("logout %s", fd2serv[fd].id)) id2fd[fd2serv[fd].id] = nil fd2serv[fd] = nil end end function MSG.error(fd, msg) print("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 robot = skynet.newservice("robot") local fd = socketdriver.connect(config.host, config.port) socketdriver.start(fd) local id if id_max >= config.max then while true do id = math.randomInt(1, config.max) 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) 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 < config.online then for i = curCount + 1, config.online do add_robot() end end -- log(string_format("online %s", curCount)) skynet.timeout(100, online) end local function start() log("start testing ...") for i = 1, config.online, config.inpre do for j = 1, config.inpre do add_robot() end skynet.sleep(100) end -- 每秒检查补充在线人数 online() end skynet.start(function() skynet.fork(start) end)