菜鸟-创作你的创作

skynet.rawcall使用应用场景分析

下面给你整理一份 《skynet.rawcall 使用与应用场景分析(超全)》,重点讲解 rawcall 的作用、原理、使用方法及典型应用场景。


一、skynet.rawcall 是什么?

在 Skynet 框架中,skynet.rawcallskynet.call 的底层版本。

原型:

skynet.rawcall(addr, typename, session, ...)

参数说明:

参数说明
addr目标服务地址(名字或 handle)
typename消息类型,例如 "lua"
session会话 ID(可为 0)
...消息内容(需自行序列化)

二、rawcall 与 call / send 对比

功能sendcallrawcall
是否阻塞
自动挂起协程
自动解包返回
使用场景通知同步 RPC高性能自定义 RPC / 内部消息

简单理解:


三、rawcall 的底层原理

  1. 直接发送消息
    • 将消息封装成 skynet_msg 结构发送到目标服务
  2. 不挂起 coroutine
    • 不会阻塞调用方
    • 适合在底层消息队列中处理大量请求
  3. 手动处理 session
    • 调用方需要管理 session ID
    • 目标服务返回时需用 skynet.retskynet.response

四、rawcall 的典型使用方法

1. 客户端调用 rawcall

local skynet = require "skynet"

-- 获取下一个 session
local session = skynet.context()
-- 发送 rawcall
skynet.rawcall(".user", "lua", session, "getName", 1001)

特点:

2. 服务端响应

skynet.dispatch("lua", function(session, source, cmd, ...)
    if cmd == "getName" then
        local name = "User_" .. ...
        skynet.ret(skynet.pack(name))  -- 将结果返回给 session
    end
end)

注意:rawcall 的返回值需要 手动处理,不会自动解包。


五、rawcall 的应用场景分析

1. 高性能批量消息

示例:

for i = 1, 1000 do
    skynet.rawcall(".log", "lua", 0, "writeLog", "msg"..i)
end


2. 内部低级 RPC


3. 自定义 session 管理

示例:

local session = math.random(1, 100000)
pending[session] = callback
skynet.rawcall(".user", "lua", session, "getUser", uid)


4. 与 skynet.queue / coroutine 结合


六、使用注意事项

  1. 不会挂起协程
    • rawcall 返回后,调用方不会等待结果
    • 必须手动管理返回值
  2. session 管理
    • session 唯一且对应返回消息
    • 常用表存储回调函数
  3. 与 call 混用
    • rawcall + call 可以组合
    • call 用于普通 RPC,rawcall 用于批量或内部异步
  4. 异常处理
    • rawcall 不自动捕获错误,需要手动 pcall

七、rawcall 实战示例

1. 批量异步请求

local skynet = require "skynet"

local pending = {}

function asyncGetName(uid, callback)
    local session = math.random(1,100000)
    pending[session] = callback
    skynet.rawcall(".user", "lua", session, "getName", uid)
end

-- 假设用户列表
local users = {1001,1002,1003}
for _, uid in ipairs(users) do
    asyncGetName(uid, function(name)
        print("UserName:", name)
    end)
end

2. 服务端统一返回

skynet.dispatch("lua", function(session, source, cmd, ...)
    if cmd == "getName" then
        local name = "User_" .. ...
        skynet.ret(skynet.pack(name))
    end
end)


八、总结

特性skynet.callskynet.sendskynet.rawcall
阻塞
协程挂起
自动解包返回
适用场景普通 RPC通知 / 单向消息高性能批量 / 内部异步 / 自定义 session

核心结论
rawcall 适合 对性能要求高、消息量大或需要自定义 session 管理的场景,而普通 RPC 使用 call 更简单方便。

退出移动版