skynet.dispatch 使用示例詳解
skynet.dispatch 函數(shù)詳解
skynet.dispatch
是 Skynet 框架中用于注冊消息處理函數(shù)的核心 API。它的作用是為特定類型的消息綁定處理邏輯,當服務(wù)收到該類型的消息時,自動調(diào)用對應(yīng)的處理函數(shù)。以下是其詳細解析:
1. 函數(shù)定義與參數(shù)
skynet.dispatch(type, func)
type
:消息類型(字符串或數(shù)字)。- 常見類型:
"lua"
:默認的 Lua 消息協(xié)議(對應(yīng)skynet.PTYPE_LUA
)。"socket"
:網(wǎng)絡(luò)消息(對應(yīng)skynet.PTYPE_SOCKET
)。- 自定義類型:通過
skynet.register_protocol
注冊的協(xié)議類型。
- 常見類型:
func
:消息處理函數(shù),格式為function(session, source, ...)
。session
:會話 ID,用于響應(yīng)消息(如skynet.ret
)。source
:發(fā)送方服務(wù)的地址(skynet.address
格式)。...
:消息內(nèi)容(由協(xié)議定義的解包邏輯生成)。
2. 消息處理流程
當服務(wù)收到一條消息時,Skynet 會執(zhí)行以下步驟:
- 協(xié)議匹配:根據(jù)消息類型(如
"lua"
)找到對應(yīng)的解包函數(shù)。 - 消息解包:調(diào)用協(xié)議注冊的
unpack
函數(shù),將二進制數(shù)據(jù)解析為 Lua 值。 - 分發(fā)處理:調(diào)用
skynet.dispatch
注冊的處理函數(shù),傳入session
、source
和解包后的數(shù)據(jù)。 - 協(xié)程調(diào)度:處理函數(shù)在一個獨立的協(xié)程中執(zhí)行,避免阻塞其他消息處理。
3. 使用示例
示例 1:處理 Lua 協(xié)議消息
local skynet = require "skynet" -- 注冊 Lua 類型消息的處理函數(shù) 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")) end end) skynet.start(function() -- 服務(wù)初始化代碼 end)
說明:
- 當收到
"lua"
類型的消息時,解析出命令cmd
和參數(shù)。 - 根據(jù)
cmd
執(zhí)行邏輯,并通過skynet.ret
返回結(jié)果。
示例 2:處理自定義協(xié)議消息
local skynet = require "skynet" -- 注冊自定義協(xié)議 skynet.register_protocol { name = "myproto", id = 100, -- 自定義協(xié)議 ID(需唯一) unpack = function(msg, sz) -- 自定義解包邏輯(如 sproto 解析) return myproto.decode(msg, sz) end } -- 處理自定義協(xié)議消息 skynet.dispatch("myproto", function(session, source, data) print("Received:", data) skynet.ret() -- 無返回值 end) skynet.start(function() -- 服務(wù)初始化代碼 end)
- 自定義協(xié)議需要先通過
skynet.register_protocol
注冊。 - 收到類型為
"myproto"
的消息時,調(diào)用自定義解包函數(shù),并處理數(shù)據(jù)。
4. 關(guān)鍵機制
(1) 協(xié)程與阻塞操作
- 協(xié)程調(diào)度:每條消息的處理在獨立協(xié)程中執(zhí)行,互不阻塞。
- 阻塞 API:若處理函數(shù)中調(diào)用
skynet.call
、skynet.sleep
等阻塞 API,當前協(xié)程會被掛起,直到操作完成。
skynet.dispatch("lua", function(session, source, cmd) if cmd == "slow_task" then skynet.sleep(100) -- 掛起協(xié)程 1 秒 skynet.ret("Done") end end)
(2) 消息響應(yīng)
skynet.ret
:用于向發(fā)送方返回響應(yīng)。- 若消息是請求(
skynet.call
),必須調(diào)用skynet.ret
。 - 若消息是通知(
skynet.send
),無需返回。
- 若消息是請求(
skynet.dispatch("lua", function(session, source, cmd) if session ~= 0 then -- 需要響應(yīng) skynet.ret(skynet.pack("Response")) end end)
5. 與 skynet.register_protocol 的協(xié)作
協(xié)議注冊:定義如何解析和打包消息。
skynet.register_protocol { name = "binary", id = skynet.PTYPE_USER, -- 自定義 ID unpack = function(msg, sz) return msg, sz end, -- 不解包,直接傳遞原始數(shù)據(jù) pack = skynet.pack -- 默認打包函數(shù) }
消息分發(fā):通過 skynet.dispatch
綁定處理邏輯。
skynet.dispatch("binary", function(session, source, msg, sz) -- 處理二進制數(shù)據(jù) end)
6. 注意事項
避免阻塞主線程:
若處理函數(shù)中有耗時操作(如大量計算、同步 IO),應(yīng)使用 skynet.fork
創(chuàng)建新協(xié)程。
skynet.dispatch("lua", function(session, source, cmd) if cmd == "heavy_task" then skynet.fork(function() -- 在子協(xié)程中執(zhí)行耗時操作 local result = heavy_compute() skynet.ret(skynet.pack(result)) end) end end)
協(xié)程生命周期:
確保每個協(xié)程最終退出,避免內(nèi)存泄漏(如通過 pcall
捕獲異常)。
線程安全:
Skynet 服務(wù)是單線程的,但協(xié)程間共享 Lua 虛擬機狀態(tài),需謹慎處理共享數(shù)據(jù)(推薦使用 skynet.sharedata
)。
7. 典型應(yīng)用場景
- RPC 調(diào)用:處理遠程服務(wù)請求并返回結(jié)果。
- 網(wǎng)絡(luò)消息:解析 TCP/UDP 數(shù)據(jù)包,如游戲協(xié)議、HTTP 請求。
- 定時任務(wù):通過
skynet.timeout
觸發(fā)延時邏輯。
總結(jié)
skynet.dispatch
是 Skynet 服務(wù)的消息處理入口,通過綁定協(xié)議類型與處理函數(shù),實現(xiàn)靈活的消息分發(fā)機制。理解其協(xié)程調(diào)度、協(xié)議注冊和響應(yīng)機制,是構(gòu)建高效 Skynet 服務(wù)的關(guān)鍵。結(jié)合 sproto
等協(xié)議工具,可以進一步簡化網(wǎng)絡(luò)通信的復雜性。
到此這篇關(guān)于skynet.dispatch 使用示例詳解的文章就介紹到這了,更多相關(guān)skynet.dispatch 使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Debezium 與 Apache Kafka 的集成方式步驟詳解
本文詳細介紹了如何將Debezium與Apache Kafka集成,包括集成概述、步驟、注意事項等,通過KafkaConnect,Debezium可以捕獲數(shù)據(jù)庫變更并實時發(fā)送到Kafka Topic,實現(xiàn)數(shù)據(jù)的實時同步和分析,感興趣的朋友一起看看吧2025-02-02ffmpeg安裝及音頻轉(zhuǎn)換指令應(yīng)用
ffmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,本文主要介紹了ffmpeg安裝及音頻轉(zhuǎn)換指令應(yīng)用,具有一定的參考價值,感興趣的可以了解一下2024-02-02偽靜態(tài)技術(shù)介紹與優(yōu)缺點分析(較完整篇)
偽靜態(tài)太適合用在普通的企業(yè)網(wǎng)站上了——既不要求高并發(fā),但同時又很在乎seo(搜索引擎優(yōu)化),而且也要求后臺可動態(tài)更新。2009-11-11