skynet skynet.send() 发送不需要应答的消息

话不多说,上测试代码

--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

测试结果如下图
skynet skynet.send() 发送不需要应答的消息_第1张图片

你可能感兴趣的:(skynet框架分析)