mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-23 19:43:09 +00:00
multicast support remote publish/subscribe
This commit is contained in:
@@ -2,10 +2,21 @@ local skynet = require "skynet"
|
||||
local mc = require "multicast.c"
|
||||
local datacenter = require "datacenter"
|
||||
|
||||
local harbor_id = skynet.harbor(skynet.self())
|
||||
|
||||
local command = {}
|
||||
local channel = {}
|
||||
local channel_n = {}
|
||||
local channel_id = skynet.harbor(skynet.self())
|
||||
local channel_remote = {}
|
||||
local channel_id = harbor_id
|
||||
|
||||
local function get_address(t, id)
|
||||
local v = assert(datacenter.get("multicast", id))
|
||||
t[id] = v
|
||||
return v
|
||||
end
|
||||
|
||||
local node_address = setmetatable({}, { __index = get_address })
|
||||
|
||||
function command.NEW()
|
||||
channel[channel_id] = {}
|
||||
@@ -15,16 +26,68 @@ function command.NEW()
|
||||
return ret
|
||||
end
|
||||
|
||||
function command.PUB(source, c, pack, size)
|
||||
local function remote_publish(node, channel, source, ...)
|
||||
skynet.redirect(node_address[node], source, "multicast", channel, ...)
|
||||
end
|
||||
|
||||
local function publish(c , source, pack, size)
|
||||
local group = assert(channel[c])
|
||||
mc.bind(pack, channel_n[c])
|
||||
local msg = skynet.tostring(pack, size)
|
||||
for k in pairs(group) do
|
||||
skynet.redirect(k, source, "multicast", c , msg)
|
||||
end
|
||||
local remote = channel_remote[c]
|
||||
if remote then
|
||||
local _, msg, sz = mc.unpack(pack, size)
|
||||
local msg = skynet.tostring(msg,sz)
|
||||
for node in pairs(remote) do
|
||||
remote_publish(node, c, source, msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
skynet.register_protocol {
|
||||
name = "multicast",
|
||||
id = skynet.PTYPE_MULTICAST,
|
||||
unpack = function(msg, sz)
|
||||
return mc.packremote(msg, sz)
|
||||
end,
|
||||
dispatch = publish,
|
||||
}
|
||||
|
||||
function command.PUB(source, c, pack, size)
|
||||
assert(skynet.harbor(source) == harbor_id)
|
||||
local node = c % 256
|
||||
if node ~= harbor_id then
|
||||
-- remote publish
|
||||
remote_publish(node, c, source, mc.remote(pack))
|
||||
else
|
||||
publish(c, source, pack,size)
|
||||
end
|
||||
end
|
||||
|
||||
function command.SUBR(source, c)
|
||||
local node = skynet.harbor(source)
|
||||
assert(node ~= harbor_id)
|
||||
local group = channel_remote[c]
|
||||
if group == nil then
|
||||
group = {}
|
||||
channel_remote[c] = group
|
||||
end
|
||||
group[node] = true
|
||||
end
|
||||
|
||||
function command.SUB(source, c)
|
||||
local node = c % 256
|
||||
if node ~= harbor_id then
|
||||
-- remote group
|
||||
if channel[c] == nil then
|
||||
channel[c] = {}
|
||||
channel_n[c] = 0
|
||||
skynet.call(node_address[node], "lua", "SUBR", c)
|
||||
end
|
||||
end
|
||||
local group = assert(channel[c])
|
||||
if not group[source] then
|
||||
channel_n[c] = channel_n[c] + 1
|
||||
@@ -32,19 +95,30 @@ function command.SUB(source, c)
|
||||
end
|
||||
end
|
||||
|
||||
function command.USUBR(source, c)
|
||||
local node = skynet.harbor(source)
|
||||
assert(node ~= harbor_id)
|
||||
local group = assert(channel_remote[c])
|
||||
group[node] = nil
|
||||
end
|
||||
|
||||
function command.USUB(source, c)
|
||||
local group = assert(channel[c])
|
||||
if group[source] then
|
||||
group[source] = nil
|
||||
channel_n[c] = channel_n[c] - 1
|
||||
if channel_n[c] == 0 then
|
||||
local node = c % 256
|
||||
if node ~= harbor_id then
|
||||
-- remote group
|
||||
channel[c] = nil
|
||||
channel_n[c] = nil
|
||||
skynet.call(node_address[node], "lua", "USUBR", c)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
skynet.register_protocol {
|
||||
name = "multicast",
|
||||
id = skynet.PTYPE_MULTICAST,
|
||||
}
|
||||
|
||||
skynet.start(function()
|
||||
skynet.dispatch("lua", function(_,source, cmd, ...)
|
||||
local f = assert(command[cmd])
|
||||
|
||||
Reference in New Issue
Block a user