start.lua 3.11 KB
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)