您的位置 首页 知识

skynet.dispatch使用示例详解 skynet api

skynet.dispatch使用示例详解 skynet api

目录
  • skynet.dispatch 函数详解
  • 1. 函数定义与参数
  • 2. 消息处理流程
  • 3. 使用示例
    • 示例 1:处理 Lua 协议消息
    • 示例 2:处理自定义协议消息
  • 4. 关键机制
    • (1) 协程与阻塞操作
    • (2) 消息响应
  • 5. 与 skynet.register_protocol 的协作
    • 6. 注意事项
      • 7. 典型应用场景
        • 拓展资料

          skynet.dispatch 函数详解

          skynet.dispatch 是 Skynet 框架中用于注册消息处理函数的核心 API。它的影响是为特定类型的消息绑定处理逻辑,当服务收到该类型的消息时,自动调用对应的处理函数。下面内容是其详细解析:

          1. 函数定义与参数

          skynet.dispatch(type, func)

          • type:消息类型(字符串或数字)。
            • 常见类型:
              • "lua":默认的 Lua 消息协议(对应 skynet.PTYPE_LUA)。
              • "socket":网络消息(对应 skynet.PTYPE_SOCKET)。
              • 自定义类型:通过 skynet.register_protocol 注册的协议类型。
          • func:消息处理函数,格式为 function(session, source, ...)
            • session:会话 ID,用于响应消息(如 skynet.ret)。
            • source:发送方服务的地址(skynet.address 格式)。
            • ...:消息内容(由协议定义的解包逻辑生成)。

          2. 消息处理流程

          当服务收到一条消息时,Skynet 会执行下面内容步骤:

          • 协议匹配:根据消息类型(如 "lua")找到对应的解包函数。
          • 消息解包:调用协议注册的 unpack 函数,将二进制数据解析为 Lua 值。
          • 分发处理:调用 skynet.dispatch 注册的处理函数,传入 sessionsource 和解包后的数据。
          • 协程调度:处理函数在一个独立的协程中执行,避免阻塞其他消息处理。

          3. 使用示例

          示例 1:处理 Lua 协议消息

          local skynet = require “skynet”– 注册 Lua 类型消息的处理函数skynet.dispatch(“lua”, function(session, source, cmd, …) if cmd == “add” then local a, b = … skynet.ret(skynet.pack(a + b)) elseif cmd == “ping” then skynet.ret(skynet.pack(“pong”)) endend)skynet.start(function() — 服务初始化代码end)

          说明

          • 当收到 "lua" 类型的消息时,解析出命令 cmd 和参数。
          • 根据 cmd 执行逻辑,并通过 skynet.ret 返回结局。

          示例 2:处理自定义协议消息

          local skynet = require “skynet”– 注册自定义协议skynet.register_protocol name = “myproto”, id = 100, — 自定义协议 ID(需唯一) unpack = function(msg, sz) — 自定义解包逻辑(如 sproto 解析) return myproto.decode(msg, sz) end}– 处理自定义协议消息skynet.dispatch(“myproto”, function(session, source, data) print(“Received:”, data) skynet.ret() — 无返回值end)skynet.start(function() — 服务初始化代码end)

          • 自定义协议需要先通过skynet.register_protocol注册。
          • 收到类型为"myproto"的消息时,调用自定义解包函数,并处理数据。

          4. 关键机制

          (1) 协程与阻塞操作

          • 协程调度:每条消息的处理在独立协程中执行,互不阻塞。
          • 阻塞 API:若处理函数中调用 skynet.callskynet.sleep 等阻塞 API,当前协程会被挂起,直到操作完成。

          skynet.dispatch(“lua”, function(session, source, cmd) if cmd == “slow_task” then skynet.sleep(100) — 挂起协程 1 秒 skynet.ret(“Done”) endend)

          (2) 消息响应

          • skynet.ret:用于向发送方返回响应。
            • 若消息是请求(skynet.call),必须调用 skynet.ret
            • 若消息是通知(skynet.send),无需返回。

          skynet.dispatch(“lua”, function(session, source, cmd) if session ~= 0 then — 需要响应 skynet.ret(skynet.pack(“Response”)) endend)

          5. 与 skynet.register_protocol 的协作

          协议注册:定义怎样解析和打包消息。

          skynet.register_protocol name = “binary”, id = skynet.PTYPE_USER, — 自定义 ID unpack = function(msg, sz) return msg, sz end, — 不解包,直接传递原始数据 pack = skynet.pack — 默认打包函数}

          消息分发:通过 skynet.dispatch 绑定处理逻辑。

          skynet.dispatch(“binary”, function(session, source, msg, sz) — 处理二进制数据end)

          6. 注意事项

          避免阻塞主线程
          若处理函数中有耗时操作(如大量计算、同步 IO),应使用 skynet.fork 创建新协程。

          skynet.dispatch(“lua”, function(session, source, cmd) if cmd == “heavy_task” then skynet.fork(function() — 在子协程中执行耗时操作 local result = heavy_compute() skynet.ret(skynet.pack(result)) end) endend)

          协程生活周期
          确保每个协程最终退出,避免内存泄漏(如通过 pcall 捕获异常)。

          线程安全
          Skynet 服务是单线程的,但协程间共享 Lua 虚拟机情形,需谨慎处理共享数据(推荐使用 skynet.sharedata)。

          7. 典型应用场景

          • RPC 调用:处理远程服务请求并返回结局。
          • 网络消息:解析 TCP/UDP 数据包,如游戏协议、HTTP 请求。
          • 定时任务:通过 skynet.timeout 触发延时逻辑。

          拓展资料

          skynet.dispatch 是 Skynet 服务的消息处理入口,通过绑定协议类型与处理函数,实现灵活的消息分发机制。领会其协程调度、协议注册和响应机制,是构建高效 Skynet 服务的关键。结合 sproto 等协议工具,可以进一步简化网络通信的复杂性。

          到此这篇关于skynet.dispatch 使用示例详解的文章就介绍到这了,更多相关skynet.dispatch 使用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!


          返回顶部