skynet 學習筆記-sproto模塊(2)


 

雲風在skynet中繼承了sproto的傳輸協議,對比protobuf的好處是,能明文看到傳輸內容,而且skynet不需要protobuf這么功能,所以雲風也建議在lua層使用sproto來作為skynet的傳輸協議。

在examples文件夾中的agent.lua中有用到sproto的例子。下面講解一下sproto的使用過程和原理:

 

proto.lua的文件中包含一個實例協議:

 1 local sprotoparser = require "sprotoparser"
 2 
 3 local proto = {}
 4 
 5 proto.c2s = sprotoparser.parse [[
 6 .package {
 7     type 0 : integer
 8     session 1 : integer
 9 }
10 
11 handshake 1 {
12     response {
13         msg 0  : string
14     }
15 }
16 
17 get 2 {
18     request {
19         what 0 : string
20     }
21     response {
22         result 0 : string
23     }
24 }
25 
26 set 3 {
27     request {
28         what 0 : string
29         value 1 : string
30     }
31 }
32 
33 quit 4 {}
34 
35 ]]
36 
37 proto.s2c = sprotoparser.parse [[
38 .package {
39     type 0 : integer
40     session 1 : integer
41 }
42 
43 heartbeat 1 {}
44 ]]
45 
46 return proto
View Code

proto.c2s是客戶端發送個服務端的協議,proto.s2c是服務端發送客戶端的協議。

sproto的協議變量類型有integer、string、boolean。sproto協議也可以實現結構體和數組、字典。

結構體的實現可以仿造.package,結構體開頭必須是以“.”開頭,"."后面的是結構體的名字,

字典和數組的實現是類似於c指針,例子如下:

 1 local s2c = [[
 2 
 3 protoName 1 {
 4 
 5   request {
 6 
 7     arg1 0 :integer
 8 
 9     arg2 1 :*value(key)
10 
11   }
12 
13 }
14 
15 ]]
View Code

 

如果服務端要發送玩家擁有的角色信息的數組,key就是角色數組的索引數據類型,如果角色數組的索引是角色id的話,id類型是integer類型,那么key就是“integer”,

value是角色數組的頭元素。

sproto協議中也可以加注釋:在注釋內容前加上“#”符號。

sprotoparser.parse是通過sprotoparser.lua中的parse方法將協議解析成一個table,過程需要用到lpeg的庫來進行匹配。筆者到現在還沒弄懂這個parse過程,哈哈。。。

 

首先看看client.lua中的sproto的實現過程,

local sproto = require "sproto"

local host = sproto.new(proto.s2c):host "package"

local request = host:attach(sproto.new(proto.c2s))

 

sproto.new(proto.s2c):將proto.s2c闖入sproto.lua中,通過c的lsproto.c文件中的newproto方法將協議數據保存在sproto結構體中,sproto協議作為全局變量,一般情況下不需要gc,

最后返回一個sproto的table,具體實現還是要看看sproto.lua文件比較好理解。

 

host("package")是返回的sproto的table中查找“package”包頭,也就是.package結構體,和一些host的方法保存在一個新的table中,這個有點難理解,所以還是看看實現過程。

host:attach(sproto.new(proto.c2s))是通過上一步返回包頭協議,綁定在c2s的協議,返回一個負責打包協議的函數體,每次調用該函數時,傳入要打包的協議名,參數,和session就可以

得到一個協議結構體,例如:

 

1 send_request("set", { what = "hello", value = "world" })
View Code


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM