skynet:skynet.response

在前面的文章: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 錯誤消息。

二、測試結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章