问题代码如下:
local cluster = require "cluster"
skynet.start(function()
cluster.send("my_cluster_server","@my_server","hi")
skynet.exit()
end)
问题: 我这里碰到的情况是,如果第一次对cluster
的节点
进行访问,不用call
而是用send
,那么cluster.lua
中的sende
是没有该地址的,需要等到对这个节点进行call
的时候才会去获取,并且发送.
解决:在cluster.send之前先cluster.query
一下,或者用其他的方式访问cluster的服务(参考我之前的文章).又或者直接改源码.
这里我们看下skynet的源码,看看他代码是怎么写的.
查看源码可知,当目标节点没找到时,会放在task_queue
队列里,等下一次cluster.call
的时候,再去获取,代码如下
function cluster.send(node, address, ...)
-- push is the same with req, but no response
local s = sender[node]
if not s then
table.insert(task_queue[node], table.pack(address, ...)) --就是这句
else
skynet.send(sender[node], "lua", "push", address, skynet.pack(...))
end
end
再来看cluster.call
function cluster.call(node, address, ...)
-- skynet.pack(...) will free by cluster.core.packrequest
return skynet.call(get_sender(node), "lua", "req", address, skynet.pack(...))
end
这里的重点就是get_sender
.
源码如下
local function get_sender(node)
local s = sender[node]
if not s then
local q = task_queue[node]
local task = coroutine.running()
table.insert(q, task)
skynet.wait(task)
skynet.wakeup(q.confirm)
return q.sender
end
return s
end