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


     

  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/HemJohn/p/5447683.html
Copyright © 2011-2022 走看看