skynet 筆記續(xù)

啟動服務

local skynet = require"skynet"

skynet.start(function ()
       -- body
end)

啟動一個服務需要調(diào)用 skynet 的 start 接口,并向其傳入一個啟動函數(shù)墓臭。

定義消息和處理消息

skynet 的服務是用來接收和處理消息的,那么服務會接收什么樣的消息呢粟誓。通常會在傳入的啟動函數(shù)中注冊該服務能夠處理的消息類型定義和分發(fā)方式枷邪。

  1. register_protocol 用于消息定義
  2. dispatch 用于消息分發(fā)
local skynet = require"skynet"

local LUACMD = {}

function LUACMD.echo(msg)
    return msg
end

local JSONCMD = {}

function JSONCMD.echo(msg)
    print_r(json.decode(msg))
    return msg
end

skynet.start(function ()

    skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = assert(LUACMD[cmd])
        skynet.ret(skynet.pack(f(...)))
    end)

    -- 定義新的 json 消息類型
    skynet.register_protocol {
        name = "json",
        id = 20,
        pack = function(m)
            return json.encode(m)
        end,
        unpack = function(m)
            local msg_str = skynet.tostring(m)
            return json.decode(msg_str)
        end,
    }

    -- 分發(fā) json 類型的消息
    skynet.dispatch("json", function (session, source, msg)
        local cmd,args = assert(msg.cmd), msg.args
        skynet.ret(cmd(table.unpack(args)))
    end)

end)

以上代碼實現(xiàn)了 lua 、json 兩種類型消息的分發(fā)抖部,其中 lua 是系統(tǒng)已經(jīng)實現(xiàn)定義好的消息類型说贝, json 類型消息是自定義的類型。

自定義的消息類型時慎颗,需提供 name乡恕、id、pack俯萎、unpack 四個信息傲宜。name 和 id 在系統(tǒng)中需唯一,因為系統(tǒng)實現(xiàn)了十多種消息類型占用了前十多個正整數(shù)夫啊,因而將 id 設為 20函卒。pack 和 unpack 分別是消息的編碼和解碼函數(shù)。

所謂解碼撇眯,指當收到一個服務收到一個該類型的消息之后报嵌,首先會經(jīng)過 unpack 處理一遍。好比收到的 json
消息實為 json 字符串熊榛,需經(jīng)過 json.decode 成 lua 類型數(shù)據(jù)以便使用锚国。

類似的方式,當從該服務發(fā)送一條 json 消息給其他服務時来候,也會使用 pack 進行 json.encode 處理一下才會變?yōu)?json 格式字符串跷叉。當然該其他服務也需實現(xiàn)了能處理 json 消息才好。

實現(xiàn)服務間通信

大多數(shù)情況下,僅使用 lua 消息就可以很好的實現(xiàn)我們的業(yè)務云挟,因而一個服務的樣子大致是這樣:

local skynet = require"skynet"

local CMD = {}

function CMD.echo(msg)
    return msg
end

function CMD.foo()
    return "bar"
end

skynet.start(function ()
    skynet.dispatch("lua", function( session, source, cmd, ... )
        local f = assert(CMD[cmd])
        skynet.ret(skynet.pack(f(...)))
    end)
end)

按這個方式梆砸,模擬兩個 玩家服務 通過 聊天服務 互發(fā)消息。

chatd.lua

local skynet = require"skynet"
require"skynet.manager"

local agents = {}

local mt = {}
mt.__index = mt

function mt.msg(from,to,msg)
    local to_agent = assert(agents[to])
    skynet.send(to_agent,"lua","msg",from,msg)
end

function mt.add_agent(name,agent)
    agents[name] = agent
end

skynet.start(function ()

    skynet.dispatch("lua", function(session,source,cmd,...)
        local f = assert(mt[cmd])
        return skynet.ret(skynet.pack(f(...)))
    end)
    skynet.register(".chatd")
end)

agent.lua

local skynet = require"skynet"

local name

local mt = {}
mt.__index = mt

function mt.msg(from, msg)
    skynet.error(string.format("agent [%s] get msg:[%s] from agent[%s]", name,msg,from))
end

function mt.send(from,to,msg)
    local chatd = skynet.localname(".chatd")
    skynet.send(chatd,"lua","msg",from,to,msg)
end

function mt.setname(agent_name)
    name = agent_name
end


skynet.start(function (agent_name)
    name = agent_name

    skynet.dispatch("lua", function(session,source,cmd,...)
        local f = assert(mt[cmd])
        return skynet.ret(skynet.pack(f(...)))
    end)
end)

main.lua

local skynet = require"skynet"

skynet.start(function()
    local chatd = skynet.newservice("chatd") -- 啟動聊天服務
    local tom = skynet.newservice("agent")   -- 啟動玩家并設置名稱為tom
    skynet.call(tom,"lua","setname","tom")
    local jim = skynet.newservice("agent")     -- 啟動玩家并設置名稱為jim
    skynet.call(jim,"lua","setname","jim")

    skynet.call(chatd,"lua","add_agent","tom",tom) -- 把 tom 注冊到 聊天服
    skynet.call(chatd,"lua","add_agent","jim",jim)    -- 把 jim 注冊到 聊天服

    skynet.send(tom,"lua","send","tom","jim","foo")  -- 通知 tom 讓其向 jim 發(fā)消息
    skynet.send(jim,"lua","send","jim","tom","bar")    -- 通知 jim 讓其向 tom 發(fā)消息
    skynet.exit()
end)

執(zhí)行

skynet/skynet etc/config

輸出

[:00000001] LAUNCH logger 
[:00000002] LAUNCH snlua bootstrap
[:00000003] LAUNCH snlua launcher
[:00000004] LAUNCH snlua cdummy
[:00000005] LAUNCH harbor 0 4
[:00000006] LAUNCH snlua datacenterd
[:00000007] LAUNCH snlua service_mgr
[:00000008] LAUNCH snlua main
[:00000009] LAUNCH snlua chatd
[:0000000a] LAUNCH snlua agent
[:0000000b] LAUNCH snlua agent
[:00000008] KILL self
[:0000000b] agent [jim] get msg:[foo] from agent[tom]
[:00000002] KILL self
[:0000000a] agent [tom] get msg:[bar] from agent[jim]
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末园欣,一起剝皮案震驚了整個濱河市帖世,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沸枯,老刑警劉巖日矫,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绑榴,居然都是意外死亡哪轿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門翔怎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窃诉,“玉大人,你說我怎么就攤上這事赤套∑矗” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵容握,是天一觀的道長宣脉。 經(jīng)常有香客問我,道長剔氏,這世上最難降的妖魔是什么塑猖? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮谈跛,結果婚禮上萌庆,老公的妹妹穿的比我還像新娘。我一直安慰自己币旧,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布猿妈。 她就那樣靜靜地躺著吹菱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彭则。 梳的紋絲不亂的頭發(fā)上鳍刷,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音俯抖,去河邊找鬼输瓜。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的尤揣。 我是一名探鬼主播搔啊,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼北戏!你這毒婦竟也來了负芋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嗜愈,失蹤者是張志新(化名)和其女友劉穎旧蛾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蠕嫁,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡锨天,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了剃毒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片病袄。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖迟赃,靈堂內(nèi)的尸體忽然破棺而出陪拘,到底是詐尸還是另有隱情,我是刑警寧澤纤壁,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布左刽,位于F島的核電站,受9級特大地震影響酌媒,放射性物質發(fā)生泄漏欠痴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一秒咨、第九天 我趴在偏房一處隱蔽的房頂上張望喇辽。 院中可真熱鬧,春花似錦雨席、人聲如沸菩咨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抽米。三九已至,卻和暖如春糙置,著一層夾襖步出監(jiān)牢的瞬間云茸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工谤饭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留标捺,地道東北人懊纳。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像亡容,于是被迫代替她去往敵國和親嗤疯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,793評論 0 38
  • 1萍倡、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,980評論 3 119
  • 引言 對于序列化概念身弊,如果是學習過Java的人,相信一定不會陌生列敲,序列化就是將對象的數(shù)據(jù)阱佛、狀態(tài)轉換成能夠存儲或者傳...
    lindx閱讀 3,183評論 0 2
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • 計劃在工作上的作用不言而喻。因此戴而,如何在工作計劃中設定可執(zhí)行目標顯得異常重要凑术。 每年年初、季初都是設定各項目或個人...
    0372ab113946閱讀 706評論 0 2