skynet:skynet.response

  • Post author:
  • Post category:其他

在前面的文章:skynet:session 中,已经使用过 skynet.ret / skynet.retpack 对消息进行应答。但这两个函数有一个使用限制,即:消息接收与消息应答必须在同一个协程里完成,也就是说:请求被哪一个协程接收,就必须在这个协程响应。

这是因为在 skynet 中,当一个服务收到一个消息的时候,会启动一个协程来处理,并把协程句柄与发送消息的服务地址进行一一对应记录在 table 中。当需要响应时,就使用当前调用 skynet.ret / skynet.retpack 的协程句柄去 table 中查询对应的服务地址,然后把消息发给这个服务地址。

若在其他协程中调用 skynet.ret / skynet.retpack,那么就会使用该协程句柄去查询服务地址,最后肯定是查不到的。

解决方法:response 可实现接受请求与响应请求在不同协程中完成。

一、echoluamsg.lua

修改前一篇文章:skynet:session 中的 echoluamsg.lua,testforkcall.lua 与 main.lua 保持不变。

skynet = require "skynet"
require "skynet.manager"

skynet.start(function()
        skynet.register("echoluamsg")

        skynet.dispatch("lua", function(session, address, msg)
        		--先把发送服务地址以及session打包到闭包中,可以在任意地方调用
                local response = skynet.response(skynet.pack)--指定打包函数

                skynet.fork(function(msg)--开启一个新的协程来处理响应
                        skynet.sleep(500)

                        skynet.error("recv " .. msg)
                        response(true, msg:upper())--第一个参数true表示应答成功,false则应答错误消息
                 end, msg)
        end)
end)
  • local response = skynet.response(pack)

    • pack:响应消息打包函数,默认为 skynet.pack;
    • 返回值:一个闭包函数。
  • response(ok, …)
    参数 ok 的值可以是:

    • “test”:检查接收响应的服务是否存在;
    • true:发送应答 PTYPE_RESPONSE;
    • false:发送 PTYPE_ERROR 错误消息。

二、测试结果

在这里插入图片描述


版权声明:本文为u010601662原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。