From e1674f04c3364b6865b8774335b7dc638ca648aa Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Sun, 13 Jul 2014 14:54:53 +0800 Subject: [PATCH] add gateserver --- examples/main.lua | 1 + examples/watchdog.lua | 1 - service/gate.lua | 170 ++++++++++++++---------------------------- 3 files changed, 58 insertions(+), 114 deletions(-) diff --git a/examples/main.lua b/examples/main.lua index abbd2751..4a98d2eb 100644 --- a/examples/main.lua +++ b/examples/main.lua @@ -11,6 +11,7 @@ skynet.start(function() skynet.call(watchdog, "lua", "start", { port = 8888, maxclient = max_client, + nodelay = true, }) print("Watchdog listen on ", 8888) diff --git a/examples/watchdog.lua b/examples/watchdog.lua index e28ab9fb..8ead2253 100644 --- a/examples/watchdog.lua +++ b/examples/watchdog.lua @@ -33,7 +33,6 @@ function SOCKET.data(fd, msg) end function CMD.start(conf) - skynet.call(gate, "lua", "nodelay", true) skynet.call(gate, "lua", "open" , conf) end diff --git a/service/gate.lua b/service/gate.lua index 772f135a..7758175f 100644 --- a/service/gate.lua +++ b/service/gate.lua @@ -1,39 +1,41 @@ local skynet = require "skynet" +local gateserver = require "gateserver" local netpack = require "netpack" -local socketdriver = require "socketdriver" -local socket -local queue local watchdog -local maxclient -local client_number = 0 -local CMD = setmetatable({}, { __gc = function() netpack.clear(queue) end }) -local nodelay = false - local connection = {} -- fd -> connection : { fd , client, agent , ip, mode } local forwarding = {} -- agent -> connection -function CMD.open( source , conf ) - assert(not socket) - local address = conf.address or "0.0.0.0" - local port = assert(conf.port) - maxclient = conf.maxclient or 1024 +skynet.register_protocol { + name = "client", + id = skynet.PTYPE_CLIENT, +} + +local handler = {} + +function handler.open(source, conf) watchdog = conf.watchdog or source - socket = socketdriver.listen(address, port) - socketdriver.start(socket) + maxclient = conf.maxclient or 1024 end -function CMD.nodelay(source, v) - if v ~= false then - v = true +function handler.message(fd, msg, sz) + -- recv a package, forward it + local c = connection[fd] + local agent = c.agent + if agent then + skynet.redirect(agent, c.client, "client", 0, msg, sz) + else + skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz)) end - nodelay = v end -function CMD.close() - assert(socket) - socketdriver.close(socket) - socket = nil +function handler.connect(fd, addr) + local c = { + fd = fd, + ip = msg, + } + connection[fd] = c + skynet.send(watchdog, "lua", "socket", "open", fd, addr) end local function unforward(c) @@ -44,28 +46,47 @@ local function unforward(c) end end -local function start(c) - if not c.mode then - c.mode = "open" - socketdriver.start(c.fd) +local function close_fd(fd) + local c = connection[fd] + if c then + unforward(c) + connection[fd] = nil + end +end + +function handler.close(fd) + close_fd(fd) + skynet.send(watchdog, "lua", "socket", "close", fd) +end + +function handler.error(fd, msg) + close_fd(fd) + skynet.send(watchdog, "lua", "socket", "error", fd, msg) +end + +local CMD = {} + +local function unforward(c) + if c.agent then + forwarding[c.agent] = nil + c.agent = nil + c.client = nil end end function CMD.forward(source, fd, client, address) local c = assert(connection[fd]) unforward(c) - start(c) - c.client = client or 0 c.agent = address or source - forwarding[c.agent] = c + gateserver.openclient(fd) end function CMD.accept(source, fd) local c = assert(connection[fd]) unforward(c) - start(c) + gateserver.openclient(fd) end function CMD.kick(source, fd) @@ -78,89 +99,12 @@ function CMD.kick(source, fd) assert(c) - if c.mode ~= "close" then - c.mode = "close" - socketdriver.close(c.fd) - end + gateserver.closeclient(fd) end -local MSG = {} - -function MSG.data(fd, msg, sz) - -- recv a package, forward it - local c = connection[fd] - local agent = c.agent - if agent then - skynet.redirect(agent, c.client, "client", 0, msg, sz) - else - skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz)) - end +function handler.command(cmd, source, ...) + local f = assert(CMD[cmd]) + return f(source, ...) end -function MSG.more() - for fd, msg, sz in netpack.pop, queue do - MSG.data(fd, msg, sz) - end -end - -function MSG.open(fd, msg) - if client_number >= maxclient then - socketdriver.close(fd) - return - end - local c = { - fd = fd, - ip = msg, - } - connection[fd] = c - client_number = client_number + 1 - if nodelay then - socketdriver.nodelay(fd) - end - skynet.send(watchdog, "lua", "socket", "open", fd, msg) -end - -local function close_fd(fd, message) - local c = connection[fd] - if c then - unforward(c) - connection[fd] = nil - client_number = client_number - 1 - end -end - -function MSG.close(fd) - close_fd(fd) - skynet.send(watchdog, "lua", "socket", "close", fd) -end - -function MSG.error(fd, msg) - close_fd(fd) - skynet.send(watchdog, "lua", "socket", "error", fd, msg) -end - -skynet.register_protocol { - name = "socket", - id = skynet.PTYPE_SOCKET, -- PTYPE_SOCKET = 6 - 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, -} - -skynet.start(function() - skynet.dispatch("lua", function (_, address, cmd, ...) - local f = assert(CMD[cmd]) - skynet.ret(skynet.pack(f(address, ...))) - end) -end) +gateserver.start(handler)