菜鸟-创作你的创作

skynet.dispatch 使用示例详解

下面给你整理一份 《Skynet dispatch 使用示例详解(超全)》,从概念、原理到实战示例,让你彻底弄懂服务端消息处理的核心机制。


一、skynet.dispatch 是什么?

在 Skynet 框架中,所有 服务之间的消息通信,都依赖于 dispatch 来处理:

skynet.dispatch("lua", function(session, source, cmd, ...)
    -- 处理消息逻辑
end)


二、dispatch 参数详解

skynet.dispatch(proto, func)

参数说明
proto消息类型,例如 "lua""text"、自定义协议
func回调函数,形式:function(session, source, ...)

三、dispatch 使用场景

  1. 处理普通 RPC 请求
  2. 处理异步消息 / 通知
  3. 自定义协议消息
  4. 内部服务通信

四、dispatch 基本示例

服务端 user.lua

local skynet = require "skynet"

local CMD = {}

function CMD.getName(uid)
    return "User_" .. uid
end

function CMD.add(a, b)
    return a + b
end

-- 注册消息处理
skynet.start(function()
    skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = CMD[cmd]
        if f then
            skynet.ret(skynet.pack(f(...))) -- 返回结果给调用方
        else
            skynet.error("Unknown command:", cmd)
        end
    end)
end)

客户端调用

local skynet = require "skynet"

local name = skynet.call(".user", "lua", "getName", 1001)
print(name)  -- 输出:User_1001

local sum = skynet.call(".user", "lua", "add", 10, 20)
print(sum)   -- 输出:30


五、dispatch 异步消息示例

客户端发送

skynet.send(".user", "lua", "notify", "Hello World")

服务端 dispatch

skynet.dispatch("lua", function(session, source, cmd, msg)
    if cmd == "notify" then
        skynet.info("Received message:", msg)
    end
    -- session = 0,不返回
end)

特点:


六、dispatch 多协议示例

-- 处理 lua 消息
skynet.dispatch("lua", function(session, source, cmd, ...)
    print("Lua message:", cmd, ...)
end)

-- 处理 text 消息
skynet.dispatch("text", function(session, source, msg)
    print("Text message:", msg)
end)


七、dispatch + rawcall 示例

skynet.dispatch("lua", function(session, source, cmd, ...)
    if cmd == "getName" then
        local reply = "User_" .. ...
        skynet.ret(skynet.pack(reply))  -- 可用于 rawcall 或 call
    end
end)


八、dispatch 高级用法

1. 使用 CMD 表集中管理命令

local CMD = {}

function CMD.hello()
    return "Hello Skynet"
end

function CMD.add(a, b)
    return a + b
end

skynet.dispatch("lua", function(session, source, cmd, ...)
    local f = CMD[cmd]
    if f then
        skynet.ret(skynet.pack(f(...)))
    else
        skynet.error("Unknown cmd:", cmd)
    end
end)

2. 防止并发冲突

local skynet = require "skynet"
local queue = require "skynet.queue"
local q = queue()

skynet.dispatch("lua", function(session, source, cmd, ...)
    q(function()
        -- 顺序处理 cmd
        skynet.ret(skynet.pack(CMD[cmd](...)))
    end)
end)


九、dispatch 注意事项

  1. session 管理
    • call / rawcall 消息的 session > 0
    • send 消息 session = 0,不返回
  2. 返回值处理
    • 必须使用 skynet.ret(skynet.pack(...)) 返回结果
  3. 并发处理
    • 默认 dispatch 是并发处理的
    • 对共享资源操作建议用 skynet.queue 或自定义锁
  4. 多协议共存
    • 可以同时注册 "lua""text" 等多种协议
  5. 错误捕获
    • dispatch 内部异常不会影响 Skynet 框架,但会打印日志

十、dispatch 核心总结


退出移动版