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


 

 

posted on 2016-04-29 21:53  HemJohn  阅读(5447)  评论(0编辑  收藏  举报

导航