skynet提供一套与客户端通讯的协议sproto,设计简单,有利于lua使用,参考官方wiki https://github.com/cloudwu/skynet/wiki/Sproto。本篇介绍组装".sproto"文件以及sproto构建流程。之后,会另写一篇介绍sproto的使用方法。
1. 组装.sproto文件流程
以下面简单的test.sproto文件为例介绍.sproto文件组装流程:
-- test.sproto
.Person {
name 0 : string
id 1 : integer
email 2 : string
.PhoneNumber {
number 0 : string
type 1 : integer
}
phone 3 : *PhoneNumber
}
.AddresBook {
person 0 : *Person
}
proto1 1001 {
request {
p 0 : integer
}
response {
ret 0 : *Person
}
}
通过sparser.parse api组装.sproto文件,参数text即test.sproto文件的内容:
-- lualib/sprotoparser.lua
function sparser.parse(text, name)
local r = parser(text, name or "=text")
dump(r)
local data = encodeall(r)
sparser.dump(data)
return data
end
第3-4行,通过lpeg库将.sproto文件分析转化成一个lua表,部分结果如下,包含protocol和type两大类。protocol里包含所有的协议,每个协议有request,response,tag三个key;type里包含所有的类型,每个类型有1个或多个域(field),每个field里包含name,tag,typename等信息。
"protocol" = {
"proto1" = {
"request" = "proto1.request"
"response" = "proto1.response"
"tag" = 1001
}
}
"type" = {
"AddresBook" = {
1 = {
"array" = true
"name" = "person"
"tag" = 0
"typename" = "Person"
}
}
"Person" = {
1 = {
"name" = "name"
"tag" = 0
"typename" = "string"
}
...
第5-6行,把lua表按特定格式组装成二进制数据后,结果如下(每一行16个字节):
02 00 00 00 00 00 65 01 - 00 00 32 00 00 00 02 00
00 00 00 00 0A 00 00 00 - 41 64 64 72 65 73 42 6F
6F 6B 1A 00 00 00 16 00 - 00 00 05 00 00 00 01 00
04 00 02 00 04 00 06 00 - 00 00 70 65 72 73 6F 6E
6E 00 00 00 02 00 00 00 - 00 00 06 00 00 00 50 65
72 73 6F 6E 5A 00 00 00 - 12 00 00 00 04 00 00 00
06 00 01 00 02 00 04 00 - 00 00 6E 61 6D 65 10 00
00 00 04 00 00 00 02 00 - 01 00 04 00 02 00 00 00
69 64 13 00 00 00 04 00 - 00 00 06 00 01 00 06 00
05 00 00 00 65 6D 61 69 - 6C 15 00 00 00 05 00 00
00 01 00 06 00 08 00 04 - 00 05 00 00 00 70 68 6F
6E 65 4E 00 00 00 02 00 - 00 00 00 00 12 00 00 00
50 65 72 73 6F 6E 2E 50 - 68 6F 6E 65 4E 75 6D 62
65 72 2E 00 00 00 14 00 - 00 00 04 00 00 00 06 00
01 00 02 00 06 00 00 00 - 6E 75 6D 62 65 72 12 00
00 00 04 00 00 00 02 00 - 01 00 04 00 04