skynet.dispatch 使用示例詳解

skynet.dispatch 函數(shù)詳解
skynet.dispatch 是 Skynet 框架中用于注冊消息處理函數(shù)的核心 API。它的作用是為特定類型的消息綁定處理邏輯,當(dāng)服務(wù)收到該類型的消息時,自動調(diào)用對應(yīng)的處理函數(shù)。以下是其詳細(xì)解析:
1. 函數(shù)定義與參數(shù)
skynet.dispatch(type, func)
type:消息類型(字符串或數(shù)字)。- 常見類型:
"lua":默認(rèn)的 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. 消息處理流程
當(dāng)服務(wù)收到一條消息時,Skynet 會執(zhí)行以下步驟:
- 協(xié)議匹配:根據(jù)消息類型(如
"lua")找到對應(yīng)的解包函數(shù)。 - 消息解包:調(diào)用協(xié)議注冊的
unpack函數(shù),將二進(jìn)制數(shù)據(jù)解析為 Lua 值。 - 分發(fā)處理:調(diào)用
skynet.dispatch注冊的處理函數(shù),傳入session、source和解包后的數(shù)據(jù)。 - 協(xié)程調(diào)度:處理函數(shù)在一個獨(dú)立的協(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)說明:
- 當(dāng)收到
"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)鍵機(jī)制
(1) 協(xié)程與阻塞操作
- 協(xié)程調(diào)度:每條消息的處理在獨(dú)立協(xié)程中執(zhí)行,互不阻塞。
- 阻塞 API:若處理函數(shù)中調(diào)用
skynet.call、skynet.sleep等阻塞 API,當(dāng)前協(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 -- 默認(rèn)打包函數(shù)
}消息分發(fā):通過 skynet.dispatch 綁定處理邏輯。
skynet.dispatch("binary", function(session, source, msg, sz)
-- 處理二進(jìn)制數(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 虛擬機(jī)狀態(tài),需謹(jǐn)慎處理共享數(shù)據(jù)(推薦使用 skynet.sharedata)。
7. 典型應(yīng)用場景
- RPC 調(diào)用:處理遠(yuǎn)程服務(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ā)機(jī)制。理解其協(xié)程調(diào)度、協(xié)議注冊和響應(yīng)機(jī)制,是構(gòu)建高效 Skynet 服務(wù)的關(guān)鍵。結(jié)合 sproto 等協(xié)議工具,可以進(jìn)一步簡化網(wǎng)絡(luò)通信的復(fù)雜性。
到此這篇關(guān)于skynet.dispatch 使用示例詳解的文章就介紹到這了,更多相關(guān)skynet.dispatch 使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Debezium 與 Apache Kafka 的集成方式步驟詳解
本文詳細(xì)介紹了如何將Debezium與Apache Kafka集成,包括集成概述、步驟、注意事項等,通過KafkaConnect,Debezium可以捕獲數(shù)據(jù)庫變更并實時發(fā)送到Kafka Topic,實現(xiàn)數(shù)據(jù)的實時同步和分析,感興趣的朋友一起看看吧2025-02-02
ffmpeg安裝及音頻轉(zhuǎn)換指令應(yīng)用
ffmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,本文主要介紹了ffmpeg安裝及音頻轉(zhuǎn)換指令應(yīng)用,具有一定的參考價值,感興趣的可以了解一下2024-02-02
偽靜態(tài)技術(shù)介紹與優(yōu)缺點(diǎn)分析(較完整篇)
偽靜態(tài)太適合用在普通的企業(yè)網(wǎng)站上了——既不要求高并發(fā),但同時又很在乎seo(搜索引擎優(yōu)化),而且也要求后臺可動態(tài)更新。2009-11-11

