diff --git a/examples/agent.lua b/examples/agent.lua index 45541f70..06db1108 100644 --- a/examples/agent.lua +++ b/examples/agent.lua @@ -4,6 +4,7 @@ local socket = require "socket" local sproto = require "sproto" local sprotoloader = require "sprotoloader" +local WATCHDOG local host local send_request @@ -26,6 +27,10 @@ function REQUEST:handshake() return { msg = "Welcome to skynet, I will send heartbeat every 5 sec." } end +function REQUEST:quit() + skynet.call(WATCHDOG, "lua", "close", client_fd) +end + local function request(name, args, response) local f = assert(REQUEST[name]) local r = f(args) @@ -62,7 +67,10 @@ skynet.register_protocol { end } -function CMD.start(gate, fd) +function CMD.start(conf) + local fd = conf.client + local gate = conf.gate + WATCHDOG = conf.watchdog -- slot 1,2 set at main.lua host = sprotoloader.load(1):host "package" send_request = host:attach(sprotoloader.load(2)) @@ -77,6 +85,11 @@ function CMD.start(gate, fd) skynet.call(gate, "lua", "forward", fd) end +function CMD.disconnect() + -- todo: do something before exit + skynet.exit() +end + skynet.start(function() skynet.dispatch("lua", function(_,_, command, ...) local f = CMD[command] diff --git a/examples/client.lua b/examples/client.lua index effee9c7..92aaa16e 100644 --- a/examples/client.lua +++ b/examples/client.lua @@ -104,7 +104,11 @@ while true do dispatch_package() local cmd = socket.readstdin() if cmd then - send_request("get", { what = cmd }) + if cmd == "quit" then + send_request("quit") + else + send_request("get", { what = cmd }) + end else socket.usleep(100) end diff --git a/examples/proto.lua b/examples/proto.lua index 31b0c52d..af88a4b5 100644 --- a/examples/proto.lua +++ b/examples/proto.lua @@ -30,6 +30,8 @@ set 3 { } } +quit 4 {} + ]] proto.s2c = sprotoparser.parse [[ diff --git a/examples/watchdog.lua b/examples/watchdog.lua index 32bceed5..29111033 100644 --- a/examples/watchdog.lua +++ b/examples/watchdog.lua @@ -1,6 +1,5 @@ local skynet = require "skynet" local netpack = require "netpack" -require "skynet.manager" local CMD = {} local SOCKET = {} @@ -10,15 +9,16 @@ local agent = {} function SOCKET.open(fd, addr) skynet.error("New client from : " .. addr) agent[fd] = skynet.newservice("agent") - skynet.call(agent[fd], "lua", "start", gate, fd) + skynet.call(agent[fd], "lua", "start", { gate = gate, client = fd, watchdog = skynet.self() }) end local function close_agent(fd) local a = agent[fd] + agent[fd] = nil if a then - -- The better way is send a message to agent, and let agent exit self. - skynet.kill(a) - agent[fd] = nil + skynet.call(gate, "lua", "kick", fd) + -- disconnect never return + skynet.send(a, "lua", "disconnect") end end @@ -39,6 +39,10 @@ function CMD.start(conf) skynet.call(gate, "lua", "open" , conf) end +function CMD.close(fd) + close_agent(fd) +end + skynet.start(function() skynet.dispatch("lua", function(session, source, cmd, subcmd, ...) if cmd == "socket" then diff --git a/lualib-src/lua-netpack.c b/lualib-src/lua-netpack.c index f42e21ca..1839abe3 100644 --- a/lualib-src/lua-netpack.c +++ b/lualib-src/lua-netpack.c @@ -210,6 +210,16 @@ push_more(lua_State *L, int fd, uint8_t *buffer, int size) { } } +static void +close_uncomplete(lua_State *L, int fd) { + struct queue *q = lua_touserdata(L,1); + struct uncomplete * uc = find_uncomplete(q, fd); + if (uc) { + skynet_free(uc->pack.buffer); + skynet_free(uc); + } +} + static int filter_data_(lua_State *L, int fd, uint8_t * buffer, int size) { struct queue *q = lua_touserdata(L,1); @@ -343,6 +353,8 @@ lfilter(lua_State *L) { // ignore listen fd connect return 1; case SKYNET_SOCKET_TYPE_CLOSE: + // no more data in fd (message->id) + close_uncomplete(L, message->id); lua_pushvalue(L, lua_upvalueindex(TYPE_CLOSE)); lua_pushinteger(L, message->id); return 3; @@ -353,6 +365,8 @@ lfilter(lua_State *L) { pushstring(L, buffer, size); return 4; case SKYNET_SOCKET_TYPE_ERROR: + // no more data in fd (message->id) + close_uncomplete(L, message->id); lua_pushvalue(L, lua_upvalueindex(TYPE_ERROR)); lua_pushinteger(L, message->id); pushstring(L, buffer, size);