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); }
public RpcPackage PackMessage(RpcMessage message) { if (message.type == "request") { return(this.PackRequest(message.proto, message.request, message.session, message.ud)); } else { SprotoHelper.Assert(message.type == "response", String.Format("invalid message type: {0}", message.type)); return(this.PackResponse(message.proto, message.response, message.session, message.ud)); } }
private SprotoObject NewPackageHeader(SprotoMgr sprotomgr, UInt16 tag, Int64 session, SprotoObject ud = null) { SprotoObject header = sprotomgr.NewSprotoObject(this.package); if (tag != 0) // tag == 0 mean : response header { header["type"] = tag; } else { SprotoHelper.Assert(session != 0, "response expect session"); } if (session != 0) { header["session"] = session; } if (ud != null) { header["ud"] = ud; } return(header); }
// 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); } } }
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); }