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