public RpcPackage PackRequest(string proto, SprotoObject request = null, Int64 session = 0, SprotoObject ud = null) { //Console.WriteLine("PackRequest {0} {1} {2}",proto,request,session); SprotoProtocol protocol = this.C2S.GetProtocol(proto); UInt16 tag = protocol.tag; SprotoObject header = this.NewPackageHeader(this.C2S, tag, session, ud); this.writer.Seek(0, SprotoStream.SEEK_BEGIN); // clear stream SprotoStream writer = this.C2S.Encode(header, this.writer); if (request != null) { string expect = protocol.request; if (request.type != expect) { SprotoHelper.Error("[SprotoRpc.Request] expect '{0}' got '{1}'", expect, request.type); } writer = this.C2S.Encode(request, writer); } RpcPackage package = new RpcPackage(); package.data = this.C2S.Pack(writer.Buffer, 0, writer.Position, out package.size); if (session != 0) { SprotoHelper.Assert(!this.sessions.ContainsKey(session), String.Format("repeat session: {0}", session)); RpcMessage message = new RpcMessage(); message.session = session; message.proto = proto; message.request = request; message.tag = tag; this.sessions[session] = message; } return(package); }
private static void _Parse(SprotoMgr sprotomgr, string proto, string filename) { Lexer lexer = new Lexer(proto, filename); while (lexer.tokens.Count > 0) { Token token = lexer.tokens[0]; if ("eof" == token.type) { break; } switch (token.type) { case "word": SprotoProtocol protocol = parse_protocol(lexer, sprotomgr); sprotomgr.AddProtocol(protocol); break; case "point": lexer.pop_token(); SprotoType type = parse_type(lexer); sprotomgr.AddType(type); break; case "space": ignore(lexer, "space"); break; default: SprotoHelper.Error(lexer.error_pos(token.line, token.column) + "invalid token:<{0},{1}>", token.type, token.val); break; } } }
public SprotoProtocol GetProtocol(UInt16 tag) { SprotoProtocol protocol = null; if (!this.TagProtocols.TryGetValue(tag, out protocol)) { return(null); } return(protocol); }
public SprotoProtocol GetProtocol(string name) { SprotoProtocol protocol = null; if (!this.Protocols.TryGetValue(name, out protocol)) { return(null); } return(protocol); }
public void AddProtocol(SprotoProtocol protocol) { if (this.Protocols.ContainsKey(protocol.name)) { SprotoHelper.Error("redefined protocol name '{0}' tag is '{1}'", protocol.name, protocol.tag); } if (this.TagProtocols.ContainsKey(protocol.tag)) { SprotoHelper.Error("redefined protocol tag '{0}' name is '{1}'", protocol.tag, protocol.name); } this.Protocols.Add(protocol.name, protocol); this.TagProtocols.Add(protocol.tag, protocol); }
public RpcPackage PackResponse(string proto, SprotoObject response = null, Int64 session = 0, SprotoObject ud = null) { //Console.WriteLine("PackResponse {0} {1} {2}",proto,response,session); SprotoProtocol protocol = this.S2C.GetProtocol(proto); SprotoObject header = this.NewPackageHeader(this.S2C, 0, session, ud); this.writer.Seek(0, SprotoStream.SEEK_BEGIN); // clear stream SprotoStream writer = this.S2C.Encode(header, this.writer); if (response != null) { string expect = protocol.response; if (response.type != expect) { SprotoHelper.Error("[SprotoRpc.Response] expect '{0}' got '{1}'", expect, response.type); } writer = this.S2C.Encode(response, writer); } RpcPackage package = new RpcPackage(); package.data = this.S2C.Pack(writer.Buffer, 0, writer.Position, out package.size); return(package); }
// Parser from binary(*.spb) private static void _ParseFromBinary(SprotoMgr sprotomgr, byte[] bytes, int length) { SprotoMgr meta = SprotoParser.Parse(meta_proto); SprotoStream reader = new SprotoStream(); reader.Write(bytes, 0, length); reader.Seek(0, SprotoStream.SEEK_BEGIN); SprotoObject group = meta.Decode("group", reader); List <SprotoObject> types = null; List <SprotoObject> protocols = null; if (group.Get("type") != null) { types = group.Get("type"); foreach (SprotoObject meta_type in types) { SprotoType type = new SprotoType(); type.name = meta_type["name"]; if (meta_type.Has("fields")) { List <SprotoObject> fields = meta_type["fields"]; foreach (SprotoObject meta_field in fields) { SprotoField field = new SprotoField(); field.name = meta_field["name"]; field.tag = (UInt16)meta_field["tag"]; field.is_array = false; if (meta_field.Has("array")) { field.is_array = (bool)meta_field["array"]; } Int64 type_id; if (meta_field.Has("buildin")) { type_id = meta_field["buildin"]; field.type = SprotoParser.BuildInTypeId2Name[type_id]; if (type_id == 0 && meta_field.Has("type")) { // fixed float field.digit = (UInt16)meta_field["type"]; } else if (type_id == 2 && meta_field.Has("type")) { // binary field.type = "binary"; } } else { type_id = meta_field["type"]; SprotoObject t = types[(int)type_id]; field.type = t["name"]; // map if (meta_field.Has("key")) { SprotoHelper.Assert(field.is_array); UInt16 map_index = (UInt16)meta_field["key"]; List <SprotoObject> t_fields = t["fields"]; string name = null; foreach (SprotoObject f in t_fields) { if (f["tag"] == map_index) { name = f["name"]; break; } } SprotoHelper.Assert(name != null, String.Format("map index {0} cann't find in type '{1}'", map_index, field.type)); field.key = name; } } type.AddField(field); } } sprotomgr.AddType(type); } } if (group.Get("protocol") != null) { protocols = group.Get("protocol"); foreach (SprotoObject meta_protocol in protocols) { SprotoProtocol protocol = new SprotoProtocol(); protocol.name = meta_protocol["name"]; protocol.tag = (UInt16)meta_protocol["tag"]; if (meta_protocol["request"] != null) { Int64 request = meta_protocol["request"]; protocol.request = types[(int)request]["name"]; } if (meta_protocol["response"] != null) { Int64 response = meta_protocol["response"]; protocol.response = types[(int)response]["name"]; } bool confirm = meta_protocol["confirm"]; if (confirm) { protocol.response = null; } sprotomgr.AddProtocol(protocol); } } }
private static SprotoProtocol parse_protocol(Lexer lexer, SprotoMgr sprotomgr) { SprotoProtocol protocol = new SprotoProtocol(); Token token = expect(lexer, "word", "space"); protocol.name = token.val; // keep same behavior with cloudwu's sproto // allow { follow by protocol's tag, eg: protocol tag{ token = expect(lexer, "tag"); ignore(lexer, "space"); protocol.tag = Convert.ToUInt16(token.val); if (protocol.tag >= SprotoParser.MAX_FIELD_TAG) { SprotoHelper.Error(lexer.error_pos(token.line, token.column) + "{0} protocol's tag {1} >= {2}", protocol.name, protocol.tag, SprotoParser.MAX_FIELD_TAG); } expect(lexer, "block_start"); ignore(lexer, "space"); while (true) { token = lexer.tokens[0]; if ("eof" == token.type || "block_end" == token.type) { break; } token = expect(lexer, "word", "space"); if (token.val == "request" || token.val == "response") { string subprotocol_type = null; Token token2 = expect(lexer, "word|block_start", "space"); if (token2.type == "word") { if (token2.val != "nil") { subprotocol_type = token2.val; } } else { SprotoType typedef = new SprotoType(); typedef.name = String.Format("{0}.{1}", protocol.name, token.val); _parse_type(lexer, typedef); sprotomgr.AddType(typedef); subprotocol_type = typedef.name; } if (subprotocol_type != null) { if (token.val == "request") { protocol.request = subprotocol_type; } else { protocol.response = subprotocol_type; } } } else { SprotoHelper.Error(lexer.error_pos(token.line, token.column) + "{0}: invalid subprotocol:{1}", protocol.name, token.val); } } expect(lexer, "block_end"); if (lexer.tokens[0].type != "eof") { ignore(lexer, "space"); } string nameReq = $"{protocol.name}.request"; if (sprotomgr.GetType(nameReq) == null) { SprotoType typedef = new SprotoType { name = nameReq }; sprotomgr.AddType(typedef); protocol.request = nameReq; } string nameRes = $"{protocol.name}.response"; if (sprotomgr.GetType(nameRes) == null) { SprotoType typedef = new SprotoType { name = nameRes }; sprotomgr.AddType(typedef); protocol.response = nameRes; } return(protocol); }
public RpcMessage UnpackMessage(byte[] bytes, int size) { RpcMessage message = null; int bin_size = 0; byte[] bin = this.S2C.Unpack(bytes, 0, size, out bin_size); this.reader.Seek(0, SprotoStream.SEEK_BEGIN); // clear stream this.reader.Buffer = bin; SprotoObject header = this.S2C.Decode(this.package, this.reader); if (header["type"] != null) { // request UInt16 tag = (UInt16)header["type"]; SprotoProtocol protocol = this.S2C.GetProtocol(tag); SprotoObject request = null; if (protocol.request != null) { request = this.S2C.Decode(protocol.request, this.reader); } message = new RpcMessage(); message.type = "request"; if (header["session"] != null) { message.session = header["session"]; } if (header["ud"] != null) { message.ud = header["ud"]; } message.proto = protocol.name; message.tag = protocol.tag; message.request = request; } else { // response SprotoHelper.Assert(header["session"] != null, "session not found"); Int64 session = header["session"]; if (this.sessions.TryGetValue(session, out message)) { //Console.WriteLine("remove session {0}",session); this.sessions.Remove(session); } SprotoHelper.Assert(message != null, "unknow session"); message.type = "response"; if (header["ud"] != null) { message.ud = header["ud"]; } SprotoProtocol protocol = this.C2S.GetProtocol(message.tag); if (protocol.response != null) { SprotoObject response = this.C2S.Decode(protocol.response, this.reader); message.response = response; } } return(message); }