diff --git a/lualib/skynet/harbor.lua b/lualib/skynet/harbor.lua index a84d94ef..b5863921 100644 --- a/lualib/skynet/harbor.lua +++ b/lualib/skynet/harbor.lua @@ -7,6 +7,10 @@ function harbor.globalname(name, handle) skynet.send(".cslave", "lua", "REGISTER", name, handle) end +function harbor.queryname(name) + return skynet.call(".cslave", "lua", "QUERYNAME", name) +end + function harbor.link(id) skynet.call(".cslave", "lua", "LINK", id) end diff --git a/service/cdummy.lua b/service/cdummy.lua index fddb2c01..107c626c 100644 --- a/service/cdummy.lua +++ b/service/cdummy.lua @@ -1,6 +1,7 @@ local skynet = require "skynet" local globalname = {} +local queryname = {} local harbor = {} skynet.register_protocol { @@ -17,12 +18,39 @@ skynet.register_protocol { unpack = skynet.tostring, } +local function response_name(name) + local address = globalname[name] + if queryname[name] then + local tmp = queryname[name] + queryname[name] = nil + for _,resp in ipairs(tmp) do + resp(true, address) + end + end +end + function harbor.REGISTER(name, handle) assert(globalname[name] == nil) globalname[name] = handle + response_name(name) skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name) end +function harbor.QUERYNAME(fd, name) + local result = globalname[name] + if result then + skynet.ret(skynet.pack(result)) + return + end + local queue = queryname[name] + if queue == nil then + queue = { skynet.response() } + queryname[name] = queue + else + table.insert(queue, skynet.response()) + end +end + function harbor.LINK(id) skynet.ret() end diff --git a/service/cslave.lua b/service/cslave.lua index 8a21aa43..a75e9f36 100644 --- a/service/cslave.lua +++ b/service/cslave.lua @@ -1,9 +1,11 @@ local skynet = require "skynet" local socket = require "socket" +local table = table local slaves = {} local connect_queue = {} local globalname = {} +local queryname = {} local harbor = {} local harbor_service local monitor = {} @@ -28,7 +30,7 @@ local function monitor_clear(id) if v then monitor[id] = nil for _, v in ipairs(v) do - v() + v(true) end end end @@ -60,6 +62,17 @@ local function ready() end end +local function response_name(name) + local address = globalname[name] + if queryname[name] then + local tmp = queryname[name] + queryname[name] = nil + for _,resp in ipairs(tmp) do + resp(true, address) + end + end +end + local function monitor_master(master_fd) while true do local ok, t, id_name, address = pcall(read_package,master_fd) @@ -72,6 +85,7 @@ local function monitor_master(master_fd) end elseif t == 'N' then globalname[id_name] = address + response_name(id_name) if connect_queue == nil then skynet.redirect(harbor_service, address, "harbor", 0, "N " .. id_name) end @@ -152,6 +166,7 @@ end function harbor.REGISTER(fd, name, handle) assert(globalname[name] == nil) globalname[name] = handle + response_name(name) socket.write(fd, pack_package("R", name, handle)) skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name) end @@ -161,7 +176,7 @@ function harbor.LINK(fd, id) if monitor[id] == nil then monitor[id] = {} end - table.insert(monitor[id], skynet.response(true)) + table.insert(monitor[id], skynet.response()) else skynet.ret() end @@ -172,19 +187,34 @@ function harbor.CONNECT(fd, id) if monitor[id] == nil then monitor[id] = {} end - table.insert(monitor[id], skynet.response(true)) + table.insert(monitor[id], skynet.response()) else skynet.ret() end end +function harbor.QUERYNAME(fd, name) + local result = globalname[name] + if result then + skynet.ret(skynet.pack(result)) + return + end + local queue = queryname[name] + if queue == nil then + queue = { skynet.response() } + queryname[name] = queue + else + table.insert(queue, skynet.response()) + end +end + skynet.start(function() local master_addr = skynet.getenv "master" local harbor_id = tonumber(skynet.getenv "harbor") local slave_address = assert(skynet.getenv "address") local slave_fd = socket.listen(slave_address) skynet.error("slave connect to master " .. tostring(master_addr)) - local master_fd = socket.open(master_addr) + local master_fd = assert(socket.open(master_addr), "Can't connect to master") skynet.dispatch("lua", function (_,_,command,...) local f = assert(harbor[command]) diff --git a/test/testharborlink.lua b/test/testharborlink.lua index 031e38ec..dfdb8613 100644 --- a/test/testharborlink.lua +++ b/test/testharborlink.lua @@ -6,6 +6,7 @@ skynet.start(function() print("run skynet examples/config_log please") harbor.connect(2) print("harbor 2 connected") + print("LOG =", skynet.address(harbor.queryname "LOG")) harbor.link(2) print("disconnected") end)