话不多说,上测试代码
--receivemsg.lua 接收消息端
local skynet = require("skynet")
require("skynet.manager")
function dosomething(session,address,...)
skynet.error("recv from:",skynet.address(address),"session:",session)
local args = {...}
skynet.error("name:",args[1],"age:",args[2])
end
skynet.start(function ( ... )
skynet.register(".receivemsg")
skynet.dispatch("lua",function ( session,address,... ) --注册lua消息处理函数
dosomething(session,address,...)
end)
end)
--sendmsg.lua 发送消息端
local skynet = require("skynet")
require("skynet.manager")
skynet.start(function ( ... )
local receivemsg = skynet.localname(".receivemsg")
local r = skynet.send(receivemsg,"lua","lpl",18)
skynet.error("skynet send return value:",r)
end)
skynet.send()分析
--addr 目的地址
--p.id 消息类型
-- session = 0 发送不需要应答的消息 session都是0
--p.pack(...) 打包参数
function skynet.send(addr, typename, ...)
local p = proto[typename]
return c.send(addr, p.id, 0 , p.pack(...))
end
那么就会发送到receivermsg服务,使用 skynet.dispatch_message(…)处理消息
下一步 raw_dispatch_message()跑到这里
--传入的参数为
prototype = 10
session = 0
local function raw_dispatch_message(prototype, msg, sz, session, source)
-- skynet.PTYPE_RESPONSE = 1, read skynet.h
if prototype == 1 then
local co = session_id_coroutine[session]
if co == "BREAK" then
session_id_coroutine[session] = nil
elseif co == nil then
unknown_response(session, source, msg, sz)
else
local tag = session_coroutine_tracetag[co]
if tag then c.trace(tag, "resume") end
session_id_coroutine[session] = nil
suspend(co, coroutine_resume(co, true, msg, sz))
end
else
local p = proto[prototype]
if p == nil then
if prototype == skynet.PTYPE_TRACE then
-- trace next request
trace_source[source] = c.tostring(msg,sz)
elseif session ~= 0 then
c.send(source, skynet.PTYPE_ERROR, session, "")
else
unknown_request(session, source, msg, sz, prototype)
end
return
end
local f = p.dispatch --因为receivemsg服务注册了消息处理函数 所以 f 为真
if f then
local ref = watching_service[source]
if ref then
watching_service[source] = ref + 1
else
watching_service[source] = 1
end
local co = co_create(f) //创建一个线程或在协程池中唤醒一个线程
session_coroutine_id[co] = session
session_coroutine_address[co] = source
local traceflag = p.trace
if traceflag == false then
-- force off
trace_source[source] = nil
session_coroutine_tracetag[co] = false
else
local tag = trace_source[source]
if tag then
trace_source[source] = nil
c.trace(tag, "request")
session_coroutine_tracetag[co] = tag
elseif traceflag then
-- set running_thread for trace
running_thread = co
skynet.trace()
end
end
suspend(co, coroutine_resume(co, session,source, p.unpack(msg,sz))) //唤醒协程 传入参数 执行receivemsg 中的dosomething 完毕后执行suspend 参数是co true SUSPEND
else
trace_source[source] = nil
if session ~= 0 then
c.send(source, skynet.PTYPE_ERROR, session, "")
else
unknown_request(session, source, msg, sz, proto[prototype].name)
end
end
end
end