zoukankan      html  css  js  c++  java
  • 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


     

  • 相关阅读:
    使用kbmmw 生成REST 服务OpenAPI函数原型
    kbmmw 5.08 正式发布
    在datasnap 中使用unidac 访问数据(客户端)
    使用双引擎,让kbmmw 的客户端访问更方便
    使用kbmMWConfiguration 让 kbmmw smartservice 更聪明
    CE lua脚本
    error LNK2019: 无法解析的外部符号 __vsnwprintf,该符号在函数 "long __stdcall StringVPrintfWorkerW
    安装 directx sdk 出现 S1023 解决
    dx11的一些数据结构
    git 比较 change to be committed
  • 原文地址:https://www.cnblogs.com/HemJohn/p/5447683.html
Copyright © 2011-2022 走看看