Code Monkey home page Code Monkey logo

sproto-csharp's Introduction

sproto-Csharp

A pure C# implementation of sproto. and using sprotodump compiler for C# language on your .sproto file to generate data access classes.

Tutorials

You write a Member.sproto file :

  .Person {
    name 0 : string
    id 1 : integer
    email 2 : string

    .PhoneNumber {
        number 0 : string
        type 1 : integer
    }

    phone 3 : *PhoneNumber
}

.AddressBook {
    person 0 : *Person
}

Then you compile it with sprotodump, to produce code in C#.

$ lua sprotodump.lua
usage: lua sprotodump.lua [[<out_option> <out>] ...] <option> <sproto_file ...>

  out_option:
    -d               dump to speciffic dircetory
    -o               dump to speciffic file
    -p               set package name(only cSharp code use)

  option: 
    -cs              dump to cSharp code file
    -spb             dump to binary spb  file
$
$ lua sprotodump.lua -cs Member.sproto  -o Member.cs

Then you use that code like this:

AddressBook address = new AddressBook ();
address.person = new System.Collections.Generic.List<Person> ();

Person person = new Person ();
person.name = "Alice";
person.id = 10000;

person.phone = new System.Collections.Generic.List<Person.PhoneNumber> ();
Person.PhoneNumber num1 = new Person.PhoneNumber ();
num1.number = "123456789";
num1.type = 1;
person.phone.Add (num1);

serialize and deserialize :

byte[] data = address.encode ();                  // encode to bytes

Sproto.SprotoStream stream = new SprotoStream (); // encode to stream
address.encode(stream);

Sproto.SprotoPack spack = new Sproto.SprotoPack ();
byte[] pack_data = spack.pack (data);             // pack
byte[] unpack_data = spack.unpack(pack_data);     // unpack

AddressBook obj = new AddressBook(unpack_data);   // decode

protocol

the Test.sproto file:

Foobar 1 {
  request {
    what 0 : string
  }
  response {
    ok 0 : boolean
  }
}

dump to c# code:

public class Protocol : ProtocolBase {
  public static  Protocol Instance = new Protocol();
  static Protocol() {
    Protocol.SetProtocol<Foobar> (Foobar.Tag);
    Protocol.SetRequest<SprotoType.Foobar.request> (Foobar.Tag);
    Protocol.SetResponse<SprotoType.Foobar.response> (Foobar.Tag);

  }

  public class Foobar {
    public const int Tag = 1;
  }
}

RPC API

Read TestCaseRpc.cs for detail.

Use in Unity

sproto-Unity

benchmark

in my i5-3470 @3.20GHz :

library encode 1M times decode 1M times
sproto-Csharp 2.84s 3.00s
sproto-Csharp(unpack) 1.36s 2.12s
protobuf-net 6.97s 8.09s

sproto-csharp's People

Contributors

lvzixun avatar m2q1n9 avatar vmtime avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sproto-csharp's Issues

函数命名问题

函数有些是驼峰式的命名,有些是下划线式的命名,能否全部改成统一的命名风格,比如全部改成驼峰式的命名?

fill_size的参数判断是否有问题

文件 SprotoTypeSerialize.cs 第82行的限制是否有问题,为何不允许sz为0的情况,例如空字符串

    private void fill_size(int sz) {
        if (sz <= 0)
            SprotoTypeSize.error ("fill invaild size.");

        this.write_uint32 ((UInt32)sz);
    }

发送音频流的问题

一些数据, 比如说音频、视频、图像的数据流,System.Text.Encoding.UTF8.GetString转成string会丢失数据,使用List也不是最好的方案,能不能加一个直接填充byte[]的接口, 直接把某个tag填充byte[]数据,在encode的时候,直接把这个byte[] copy到base.serialize,decode的时候做一些特殊处理,直接从base.deserialize读出这个tag

sproto-Csharp只支持单向RPC吗?

TestCaseRpc.cs

SprotoRpc client = new SprotoRpc ();
SprotoRpc service = new SprotoRpc (Protocol.Instance);
SprotoRpc.RpcRequest clientRequest = client.Attach (Protocol.Instance);

sproto-Csharp只支持单向RPC吗?这里好像默认client只有type和session的package信息,没有protocol内容。
如果c2s和s2c各有一份协议文件,如云风的sproto项目里的testrpc.ua,怎么来实现?
用sprotodump.lua依次生成的话,Protocol.cs只会生成一份保留后一次的结构。

sproto_dump or sprotodump?

当field数量超过32时会出错

SprotoTypeFieldOP.cs中

public SprotoTypeFieldOP (int max_field_count) {
int slot_count = max_field_count / slot_bits_size;
slot_count = (slot_count > 0)?(slot_count):(1);

this.has_bits = new UInt32[slot_count];
}

slot_count的计算有误
可以修改为

int slot_count = (max_field_count + slot_bits_size - 1) / slot_bits_size;

或者添加

if (max_field_count % slot_bits_size > 0) slot_count++;

关于这个项目和skynet

现在版本的skynet,数据包头两个字节是包长度,包总长度会大2。这个sproto的rpc pack没有做这件事。这是你的原意吗?我们需要手动给byte数组再添前两位,是这样吗?

设计思路问题:客户端的发包是否带有session会严重影响服务器Response

SprotoRPC.cs中的核心函数 Dispatch中,有如下判断:
info.Response = null; if (this.package.HasSession) { long session = this.package.session; info.Response = delegate (SprotoTypeBase response) {

这样写的后果是,如果客户端发包带有session,则info.Response被赋值;如果客户端发包不带session,则info.Response不被赋值。
当客户端调整逻辑时,或刻意发送错误的包时,会导致服务器逻辑中Response出现null

这个问题会变成一个很难防范的服务器漏洞——除非我们对所有的sinfo.Response都判断是否为空,否则就会出现空引用异常,非常危险。
即便服务器做了针对null的异常处理,也会导致逻辑在执行到一半时中止(执行到Response时中止),依然有很大风险。

我目前在自己的项目中设计为:无论package.session是否存在,都给Response附上一个值,就算出问题也是客户端收包出问题,不会有更多不良影响。请考虑。

rpc.spack.pack有可能问题

SprotoRpc.cs line(55) rpc.spack.pack 返回的bytes与sproto.lua pack返回的bytes有时会不一致。
协议定义:

game_c2s_login 1000 {
    request {
        user_uid    0 : string                      # username
        token       1 : string                  # token
        version     2 : string                      # 客户端版本
        channel     3 : integer             # 哪个渠道
        zone        4 : integer             # 哪个区
        channel_username 5 : string                 # [数据分析][客服查询]用户在渠道那边的用户名
    }
    response {
        errno       0 : integer             #
        time        1 : integer             # 服务器本地时间,1970到现在的秒(北京/重庆/上海时间+8区)
        role_num    2 : integer                 # 角色数量(为零时 需要创建角色)
    }
}

测试用例:
1 { user_uid = "xxxxx", token = "1"} csharp编码pack之后与lua库输出是一致的
2 { user_uid = "xxxxx", token = "abc123"}csharp编码与lua输出是一致的,但是经过pack之后就不一致了。

这个sz是否有问题

随意看代码,隐约感觉有问题,这个sz是v.Length,而非utf8编码后的length

    public void write_string(List<string> str_list, int tag) {
        if (str_list == null || str_list.Count <= 0)
            return;

        // write size length
        int sz = 0;
        foreach (string v in str_list) {
            sz += SprotoTypeSize.sizeof_length + v.Length;
        }
        this.fill_size (sz);

        // write stirng
        foreach (string v in str_list) {
            this.encode_string (v);
        }

        this.write_tag (tag, 0);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.