當你走過一個坐在自己店門前的雜貨商面前。走過一個吸着煙斗的守門人面前,走過一個馬車夫面前時,請你給我描繪一下這個雜貨商、守門人和馬車夫,他們的姿態,他們的外貌,要用畫家那樣的細節描繪出他們的精神本質,使我不至於把他們同任何別的雜貨商人、任何別的守門人、任何別的馬車夫混同起來,還請你只用一句話就讓我知道馬車夫有一匹馬同其他的馬是不一樣的。 ——福樓拜指導莫泊桑
從今天開始,我給自己設定了幾個小目標,其中之一是:每天都寫上幾千字或者半個小時。今天是開始碼字的第一天,坐在電腦前想了好一會,從寫什么開始?目的是什么?寫什么不重要,目的是培養一下碼字的習慣。我的本職是碼代碼的。就從我了解的東西開始寫吧。今天姑且為大家介紹下:Skynet。
Skynet
Skynet是一個輕量級的游戲服務器框架。語言是C+LUA。挺干凈的。作者是雲風。社區也一直在維護。他想做的核心的一件事情就是,提供一個消息轉發機制,用C+LUA實現一個actor模式的服務器。actor模式和消息轉發機制的關系是這樣的,actor模式是一種設計模式,在此之前實體是通過多線程的鎖等機制實現讀寫數據,使用actor之后,各個實體之間的溝通改為消息傳遞。實體本身管理自己的行為和動作。不熟悉的可能不太理解。
下面介紹下Skynet的使用。
首先Git clone源碼之后,在Linux環境下編譯出Skynet。
其次,他的啟動方式,不是用lua編譯代碼跑起來,而是用編譯出的Skynet帶一個配置文件跑一個文件。這是一個新人覺得怪異的地方。
再說代碼的編寫。如上所述,這里的實體就是一個一個的服務。服務之間通過Skynet框架的消息傳遞。所以我們的核心任何有2個:
1.如何啟動一個服務。
啟動服務。
require "skyenet"
skynet.start(function()
....
skynet.newservice("服務名")
end
)
這樣算是啟動了一個服務。
newservice填的服務名,他是會在config中找到對應的服務的文件,繼續運行起來。
2.服務之間如何溝通。這個也是重點
2.1 首先服務需要想Skynet框架注冊本服務。注冊需要給什么呢?假設是你自己設計你會怎么做?每個服務需要有一個名字吧?
所以
1. 名字。作為標識。
2. 地址(相當於郵件地址,別人給你發消息的接收地址)
3. 接收消息的語種/類型(想象一下,別人寄給你一封信,可惜你都不知道這個是什么語言寫的?中文英文你知道,你分得清楚,越南文和泰文嗎?我們需要提前說清楚免得別人寫信的內容寫
4. 消息處理
錯。)
1. 解碼decode。別人的語言咱們不一定會使。咱得翻譯一下。
2. 編碼encode。
3. 來源。source。
分析處理socket的agent中的服務
1. 名字 , local watchdog = skynet.newservice("服務名") 這個服務名就是標識的名字
2. 地址 , watchdog 就是地址一個int
為什么名字和地址會在外面呢。這個也可以理解。名字和地址那是對外的。是別人用來區分和標識你的。你的名字和你家的地址當然是別人(你爸和村長)取的。
skynet.register (
name = "client" --類型名。 指示這個是客戶端消息
id = skynet.PTYPE_TEXT -- 指示skynet 數據的類型。
unpack = ... -- 解碼
pack = ... -- 編碼方式
dispath = function (type,func)
)
... 就是
dispath 分發函數,為消息類型 type ,指定一個函數處理。
,function ( session , source , cmd ,...) -- 內部轉發,session, 來源,指令 和 其他參數
end
說到這里。我們得提到通過發消息給一個服務,調用一個服務的服務了。
skynet.call ( address, type, cmd,... )
就是說,告訴address地址的服務,有一個type類型的消息,內部約定一般服務指定服務里面哪個函數(cmd),至於參數就在...里面自動填充了
然后我們看看服務內部收到了什么,session , source , cmd ,...
這里的session是指內部的一個session返回的時候調用者知道。
source是來源。
至於怎么返回,skynet.ret(skynet.pack(...))
明天繼續分解這塊:D
才一千三百字。