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

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 ]]

如果服务端要发送玩家拥有的角色信息的数组,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" })

时间: 2024-07-30 10:09:15

skynet 学习笔记-sproto模块(2)的相关文章

Python学习笔记—itertools模块

这篇是看wklken的<Python进阶-Itertools模块小结> 学习itertools模块的学习笔记 在看itertools中各函数的源代码时,刚开始还比较轻松,但后面看起来就比较费劲... 1.itertools.count(start=0,step=1) 此函数用来创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算 如果超出了sys.maxint,计数器将溢出并继续行-sys.maxint-1开始计算 定义: def count(start=0, step=1):

python学习笔记glob模块

python有许多的类库,现将学习记录下来,以供以后回顾复习: 1.glob模块 用于文件名操作,匹配指定目录下的文件,常用的有两个函数: glob(pattern),返回匹配的文件的列表. iglob(pattern),返回生成器,可以遍历匹配的文件. 示例代码: glob()bogon:datasets xuguoqiang$ ls matrixA.txt matrixB.txt test words.txt files = glob.glob('*.txt') >>> for fi

python学习笔记(模块初识、pyc和PyCodeObject是什么)

一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sys.argv) #打印相对路径,在pycharm输出结果是绝对路径,因为在pycharm中调用 print(sys.argv[2]) #可以从数据列表中取值,[2]指取第三位.        标准库存放位置:C:\Python35\Lib 第三方库存放位置C:\Python35\Lib\site-p

python学习笔记(八)-模块

大型python程序以模块和包的形式组织.python标准库中包含大量的模块.一个python文件就是一个模块.1.标准模块 python自带的,不需要你安装的2.第三方模块 需要安装,别人提供的. pip install xxx 自动化安装的 手动安装 首先下载安装包 解压 在命令行里面进入到这个解压之后的目录 执行python setup.py install3.自己写的 自己写的python文件import xx 导入一个文件 ,导入文件的实质是什么,把这个python运行一次import

python自动化测试学习笔记-6urllib模块&amp;request模块

python3的urllib 模块提供了获取页面的功能. urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) -         url:  需要打开的网址 -         data:Post提交的数据 -         timeout:设置网站的访问超时时间 直接用urllib.request模块的urlopen()获取页

Python学习笔记-邮件模块SMTP

smtplib模块: SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. python的smtplib提供了一种很方便的途径发送电子邮件.它对smtp协议进行了简单的封装. Python创建 SMTP 对象语法如下: import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] ) 参数说明: hos

Python学习笔记-常用模块

1.python模块 如果你退出 Python 解释器并重新进入,你做的任何定义(变量和方法)都会丢失.因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作为输入执行.这就是传说中的 脚本.随着你的程序变得越来越长,你可能想要将它分割成几个更易于维护的文件.你也可能想在不同的程序中使用顺手的函数,而不是把代码在它们之间中拷来拷去. 为了满足这些需要,Python 提供了一个方法可以从文件中获取定义,在脚本或者解释器的一个交互式实例中使用.这样的文件被称

【python学习笔记】模块导入搜索路径的搜索顺序是什么?

搜索顺序应该是? 内置模块 ->主目录 ->PYTHONPATH环境变量 ->标准库 ->.pth文件指定的内容 所以如果主目录里有一个自定义的模块文件文件,应该会先加载,然后后面标准库的模块文件可能就不会加载了,也就是隐藏了. 还是实验一下: 创建一个sys.py在主目录下,以下是在windows的py3.5上实验的,sys.py内容: # filename sys.py in current working directory def func():     print('Th

python 学习笔记 os模块常用项

删除指定目录树中的空目录 #!/usr/bin env python import os import sys dir =sys.argv[1] if os.path.isdir(dir):    for root,dirs,files in os.walk(dir,topdown=False):#从最里向外遍历       for d in dirs:          if not os.listdir(os.path.join(root,d)):#判断目录是否为空