Introduction
======
Sproto is an efficient serialization library for C, and focuses on lua binding. It's like Google protocol buffers, but much faster.
The design is simple. It only supports a few types that lua supports. It can be easily bound to other dynamic languages, or be used directly in C.
In my i5-2500 @3.3GHz CPU, the benchmark is below:
The schema in sproto:
```
.Person {
name 0 : string
id 1 : integer
email 2 : string
.PhoneNumber {
number 0 : string
type 1 : integer
}
phone 3 : *PhoneNumber
}
.AddressBook {
person 0 : *Person
}
```
It's equal to:
```
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
message PhoneNumber {
required string number = 1;
optional int32 type = 2 ;
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
```
Use the data:
```lua
local ab = {
person = {
{
name = "Alice",
id = 10000,
phone = {
{ number = "123456789" , type = 1 },
{ number = "87654321" , type = 2 },
}
},
{
name = "Bob",
id = 20000,
phone = {
{ number = "01234567890" , type = 3 },
}
}
}
}
```
library| encode 1M times | decode 1M times | size
-------| --------------- | --------------- | ----
sproto | 2.15s | 7.84s | 83 bytes
sproto (nopack) |1.58s | 6.93s | 130 bytes
pbc-lua | 6.94s | 16.9s | 69 bytes
lua-cjson | 4.92s | 8.30s | 183 bytes
* pbc-lua is a google protocol buffers library https://github.com/cloudwu/pbc
* lua-cjson is a json library https://github.com/efelix/lua-cjson
Parser
=======
```lua
local parser = require "sprotoparser"
```
* `parser.parse` parses a sproto schema to a binary string.
The parser is needed for parsing the sproto schema. You can use it to generate binary string offline. The schema text and the parser is not needed when your program is running.
Lua API
=======
```lua
local sproto = require "sproto"
local sprotocore = require "sproto.core" -- optional
```
* `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser).
* `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser).
* `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto).
* `sproto.parse(schema)` creares a sproto object by a schema text string (by calling parser.parse)
* `sproto:exist_type(typename)` detect whether a type exist in sproto object.
* `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string.
* `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed.
* `sproto:pencode(typename, luatable)` The same with sproto:encode, but pack (compress) the results.
* `sproto:pdecode(typename, blob [,sz])` The same with sproto.decode, but unpack the blob (generated by sproto:pencode) first.
* `sproto:default(typename, type)` Create a table with default values of typename. Type can be nil , "REQUEST", or "RESPONSE".
RPC API
=======
There is a lua wrapper for the core API for RPC .
`sproto:host([packagename])` creates a host object to deliver the rpc message.
`host:dispatch(blob [,sz])` unpack and decode (sproto:pdecode) the binary string with type the host created (packagename).
If .type is exist, it's a REQUEST message with .type , returns "REQUEST", protoname, message, responser, .ud. The responser is a function for encode the response message. The responser will be nil when .session is not exist.
If .type is not exist, it's a RESPONSE message for .session . Returns "RESPONSE", .session, message, .ud .
`host:attach(sprotoobj)` creates a function(protoname, message, session, ud) to pack and encode request message with sprotoobj.
If you don't want to use host object, you can also use these following apis to encode and decode the rpc message:
`sproto:request_encode(protoname, tbl)` encode a request message with protoname.
`sproto:response_encode(protoname, tbl)` encode a response message with protoname.
`sproto:request_decode(protoname, blob [,sz])` decode a request message with protoname.
`sproto:response_decode(protoname, blob [,sz]` decode a response message with protoname.
Read testrpc.lua for detail.
Schema Language
==========
Like Protocol Buffers (but unlike json), sproto messages are strongly-typed and are not self-describing. You must define your message structure in a special language.
You can use sprotoparser library to parse the schema text to a binary string, so that the sproto library can use it.
You can parse them offline and save the string, or you can parse them during your program running.
The schema text is like this:
```
# This is a comment.
.Person { # . means a user defined type
name 0 : string # string is a build-in type.
id 1 : integer
email 2 : string
.PhoneNumber { # user defined type can be nest.
number 0 : string
type 1 : integer
}
phone 3 : *PhoneNumber # *PhoneNumber means an array of PhoneNumber.
height 4 : integer(2) # (2) means a 1/100 fixed-point number.
data 5 : binary # Some binary data
}
.AddressBook {
person 0 : *Person(id) # (id) is optional, means Person.id is main index.
}
foobar 1 { # define a new protocol (for RPC used) with tag 1
request Person # Associate the type Person with foobar.request
response { # define the foobar.response type
ok 0 : boolean
}
}
```
A schema text can be self-described by the sproto schema language.
```
.type {
.field {
name 0 : string
buildin 1 : integer
type 2 : integer # type is fixed-point number precision when buildin is SPROTO_TINTEGER; When buildin is SPROTO_TSTRING, it means binary string when type is 1.
tag 3 : integer
array 4 : boolean
key 5 : integer # If key exists, array must be true, and it's a map.
}
name 0 : string
fields 1 : *field
}
.protocol {
name 0 : string
tag 1 : integer
request 2 : integer # index
response 3 : integer # index
confirm 4 : boolean # response nil where confirm == true
}
.group {
type 0 : *type
protocol 1 : *protocol
}
```
Types
=======
* **string** : string
* **binary** : binary string (it's a sub type of string)
* **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision.
* **boolean** : true or false
You can add * before the typename to declare an array.
You can also specify a main index, the array whould be encode as an unordered map.
User defined type can be any name in alphanumeric characters except the build-in typenames, and nested types are supported.
* Where are double or real types?
I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point presision.
* Where is enum?
In lua, enum types are not very useful. You can use integer to define an enum table in lua.
Wire protocol
========
Each integer number must be serialized in little-endian format.
The sproto message must be a user defined type struct, and a struct is encoded in three parts. The header, the field part, and the data part.
The tag and small integer or boolean will be encoded in field part, and others are in data part.
All the fields must be encoded in ascending order (by tag, base 0). The tags of fields can be discontinuous, if a field is nil. (default value in lua), don't encode it in message.
The header is a 16bit integer. It is the number of fields.
Each f
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
skynet_vs2017.zip (1344个子文件)
libjemalloc.so.2 3.27MB
libjemalloc_pic.a 16.59MB
libjemalloc.a 16.5MB
liblua.a 1.75MB
configure.ac 68KB
private_symbols_jet.awk 1KB
private_symbols.awk 1KB
start_skynet.bat 26B
SFMT.c 86KB
jemalloc.c 80KB
ctl.c 74KB
arena.c 63KB
extent.c 59KB
prof.c 59KB
socket_server.c 47KB
lstrlib.c 46KB
lparser.c 45KB
lvm.c 44KB
stats.c 38KB
lgc.c 36KB
lptree.c 36KB
lcode.c 34KB
lauxlib.c 33KB
lapi.c 32KB
lpcode.c 31KB
lua-bson.c 28KB
sproto.c 28KB
lua-crypt.c 26KB
background_thread.c 26KB
ldo.c 25KB
mallctl.c 23KB
loadlib.c 23KB
stats_print.c 23KB
SFMT.c 20KB
ldebug.c 20KB
liolib.c 20KB
ltable.c 20KB
skynet_server.c 20KB
tcache.c 19KB
service_harbor.c 18KB
math.c 18KB
decay.c 18KB
lua.c 18KB
lsproto.c 17KB
lua-sharedata.c 16KB
lobject.c 16KB
lua-socket.c 16KB
llex.c 16KB
lpcap.c 16KB
malloc_io.c 15KB
ckh.c 14KB
zone.c 14KB
lua-cluster.c 13KB
lbaselib.c 13KB
ltablib.c 13KB
serialize.c 13KB
ldblib.c 12KB
lua-seri.c 12KB
stats.c 12KB
base.c 12KB
lua-mongo.c 12KB
lua-skynet.c 11KB
bitmap.c 11KB
lpvm.c 11KB
lstring.c 11KB
large.c 11KB
loslib.c 11KB
lua-netpack.c 10KB
luac.c 10KB
xallocx.c 10KB
lmathlib.c 10KB
skiplist.c 10KB
service_gate.c 10KB
pages.c 10KB
lsha1.c 9KB
rtree.c 9KB
arena_reset.c 9KB
tsd.c 8KB
lstate.c 8KB
lua-datasheet.c 8KB
witness.c 8KB
malloc_io.c 8KB
rb.c 8KB
prof_reset.c 7KB
ph.c 7KB
malloc_hook.c 7KB
atomic.c 7KB
lutf8lib.c 7KB
extent_dss.c 7KB
size_classes.c 7KB
rtree.c 7KB
skynet_start.c 7KB
skynet_timer.c 7KB
extent.c 6KB
md5.c 6KB
base.c 6KB
nstime.c 6KB
lua-debugchannel.c 6KB
lundump.c 6KB
prng.c 6KB
共 1344 条
- 1
- 2
- 3
- 4
- 5
- 6
- 14
资源评论
奔走中的程序媛
- 粉丝: 4
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功