新的項(xiàng)目第一次采用skynet服務(wù)端框架做一個棋牌類的手游淹父,客戶端選型自quick-cocos2dx,雙端都是lua,復(fù)用了斗地主的核心邏輯代碼珊随,很快就把大廳和打牌邏輯完成了,下面對skynet做了一個總述梳理柿隙。
skynet是一個多線程叶洞,基于actor的游戲服務(wù)器框架,它啟動時開啟固定線程禀崖,采取二級消息隊列的分發(fā)衩辟。
它的C代碼完成了skynet框架主要的任務(wù),即消息分發(fā)和線程調(diào)度帆焕。在skynet框架里惭婿,skynet_context是可以被調(diào)度上線程的最小實(shí)體,每個邏輯服務(wù)實(shí)際上就是基于這個skynet_context上下文叶雹,它擁有一個私有消息隊列财饥,向一個服務(wù)發(fā)送一個消息就是把消息壓入私有隊列里。skynet維護(hù)一個全局隊列折晦,里面放了數(shù)個不為空的次級隊列钥星,工作線程不斷從主消息隊列里取出一個次級隊列,再從一個次級隊列里取出一條消息满着,調(diào)用對應(yīng)服務(wù)的callback函數(shù)谦炒,用戶定義的callback函數(shù)不必保證線程安全贯莺,因?yàn)樵赾allback調(diào)用過程中,其他工作線程不可能得到這個服務(wù)的次級消息隊列宁改,也就不可能被并發(fā)缕探。
在Lua層,我們可以方便地編寫出skynet服務(wù)还蹲,這個服務(wù)可以處理其它服務(wù)發(fā)送過來或者直接底層網(wǎng)絡(luò)接收到的消息爹耗,這樣,我們的lua代碼就可以運(yùn)行在多線程的環(huán)境里面了谜喊。值得說明的是潭兽,每個lua服務(wù)其實(shí)都是彼此獨(dú)立創(chuàng)建的一個Lua state,服務(wù)callback被調(diào)用時斗遏,消息壓入Lua虛擬機(jī)中山卦,skynet會為lua層的每個請求建立一個獨(dú)立的coroutine,一旦這個coroutine中發(fā)生了skynet.call(即發(fā)送一個消息包)诵次,coroutine便掛起账蓉,在lua層會記錄這個發(fā)送消息包的session和當(dāng)前coroutine,callback正常返回藻懒,當(dāng)下次帶有該session的callback被調(diào)用時剔猿,coroutine被resume,lua代碼完成一次rpc調(diào)用嬉荆。
先總結(jié)到這里归敬,祝大家使用順利!