/// <summary> /// Decode array in message. /// </summary> private void decodeArray(JsonNode_Array list, string type, JsonNode_Object proto) { if (this.util.isSimpleType(type)) { int length = (int)decodeUInt32(); for (int i = 0; i < length; i++) { list.Add(this.decodeProp(type, null)); } } else { list.Add(this.decodeProp(type, proto)); } }
/// <summary> /// If the event exists,invoke the event when server return messge. /// </summary> /// <param name="eventName"></param> /// <param name="value"></param> /// <returns></returns> /// public void InvokeOnEvent(string route, JsonNode_Object msg) { if (!this.eventMap.ContainsKey(route)) { return; } List <Action <JsonNode_Object> > list = eventMap[route]; foreach (Action <JsonNode_Object> action in list) { IEnumeratorTool.ExecAction(() => { action.Invoke(msg); }); } }
public MessageProtocol(JsonNode_Object dict, JsonNode_Object serverProtos, JsonNode_Object clientProtos) { ICollection <string> keys = dict.Keys; foreach (string key in keys) { ushort value = Convert.ToUInt16(dict[key].AsInt()); this.dict[key] = value; this.abbrs[value] = key; } protobuf = new Protobuf.Protobuf(clientProtos, serverProtos); this.encodeProtos = clientProtos; this.decodeProtos = serverProtos; this.reqMap = new Dictionary <uint, string>(); }
//Decode the user-defined object type in message. private JsonNode_Object decodeObject(string type, JsonNode_Object proto) { if (proto != null) { IJsonNode __messages; if (proto.TryGetValue("__messages", out __messages)) { IJsonNode _type; if (((JsonNode_Object)__messages).TryGetValue(type, out _type) || protos.TryGetValue("message " + type, out _type)) { int l = (int)decodeUInt32(); JsonNode_Object msg = new JsonNode_Object(); return(this.decodeMsg(msg, (JsonNode_Object)_type, this.offset + l)); } } } return(new JsonNode_Object()); }
public void Request(string route, JsonNode_Object msg, Action <JsonNode_Object> action = null, bool isNeedShowError = true) { //requests.Enqueue(new RequestMessage(route, msg, action)); requests.Enqueue(new RequestMessage(route, msg, (JsonNode_Object json) => { if (isNeedShowError) { IJsonNode error; json.TryGetValue("error", out error); if (error != null) { //UIWidgetMgr.Inst.Widget_SingleSelectWindow.Show(error.AsString()); } } // action(json); //检测绑定 CheckBind(route, json.ToString()); })); }
private JsonNode_Object buildMsg(JsonNode_Object user) { if (user == null) { user = new JsonNode_Object(); } JsonNode_Object msg = new JsonNode_Object(); //Build sys option JsonNode_Object sys = new JsonNode_Object(); sys["version"] = new JsonNode_ValueString(Version); sys["type"] = new JsonNode_ValueString(Type); //Build handshake message msg["sys"] = sys; msg["user"] = user; return(msg); }
/// <summary> /// Encode the message. /// </summary> private int encodeMsg(byte[] buffer, int offset, JsonNode_Object proto, JsonNode_Object msg) { ICollection <string> msgKeys = msg.Keys; foreach (string key in msgKeys) { IJsonNode value; if (proto.TryGetValue(key, out value)) { IJsonNode value_option; if (((JsonNode_Object)value).TryGetValue("option", out value_option)) { switch (value_option.ToString()) { case "required": case "optional": IJsonNode value_type, value_tag; if (((JsonNode_Object)value).TryGetValue("type", out value_type) && ((JsonNode_Object)value).TryGetValue("tag", out value_tag)) { offset = this.writeBytes(buffer, offset, this.encodeTag(value_type.ToString(), Convert.ToInt32(value_tag.AsInt()))); offset = this.encodeProp(msg[key], value_type.ToString(), offset, buffer, proto); } break; case "repeated": IJsonNode msg_key; if (msg.TryGetValue(key, out msg_key)) { if (msg_key.AsList().Count > 0) { offset = encodeArray(msg_key.AsList(), (JsonNode_Object)value, offset, buffer, proto); } } break; } } } } return(offset); }
/// <summary> /// Encode the message from server. /// </summary> /// <param name='route'> /// Route. /// </param> /// <param name='msg'> /// Message. /// </param> public byte[] encode(string route, JsonNode_Object msg) { byte[] returnByte = null; IJsonNode proto; if (this.protos.TryGetValue(route, out proto)) { if (!checkMsg(msg, (JsonNode_Object)proto)) { return(null); } int length = Encoder.byteLength(msg.ToString()) * 2; int offset = 0; byte[] buff = new byte[length]; offset = encodeMsg(buff, offset, (JsonNode_Object)proto, msg); returnByte = new byte[offset]; for (int i = 0; i < offset; i++) { returnByte[i] = buff[i]; } } return(returnByte); }
/// <summary> /// Decode each simple type in message. /// </summary> private IJsonNode decodeProp(string type, JsonNode_Object proto) { switch (type) { case "uInt32": return(new JsonNode_ValueNumber(decodeUInt32())); case "int32": case "sInt32": return(new JsonNode_ValueNumber(decodeSInt32())); case "float": return(new JsonNode_ValueNumber(this.decodeFloat())); case "double": return(new JsonNode_ValueNumber(this.decodeDouble())); case "string": return(new JsonNode_ValueString(this.decodeString())); default: return(this.decodeObject(type, proto)); } }
//Send notify, do not need id internal void send(string route, JsonNode_Object msg) { send(route, 0, msg); }
/// <summary> /// Encode each item in message. /// </summary> private int encodeProp(IJsonNode value, string type, int offset, byte[] buffer, JsonNode_Object proto) { switch (type) { case "uInt32": this.writeUInt32(buffer, ref offset, value); break; case "int32": case "sInt32": this.writeInt32(buffer, ref offset, value); break; case "float": this.writeFloat(buffer, ref offset, value); break; case "double": this.writeDouble(buffer, ref offset, value); break; case "string": this.writeString(buffer, ref offset, value); break; default: IJsonNode __messages; IJsonNode __message_type; if (proto.TryGetValue("__messages", out __messages)) { if (((JsonNode_Object)__messages).TryGetValue(type, out __message_type) || protos.TryGetValue("message " + type, out __message_type)) { byte[] tembuff = new byte[Encoder.byteLength(value.ToString()) * 3]; int length = 0; length = this.encodeMsg(tembuff, length, (JsonNode_Object)__message_type, (JsonNode_Object)value); offset = writeBytes(buffer, offset, Encoder.encodeUInt32((uint)length)); for (int i = 0; i < length; i++) { buffer[offset] = tembuff[i]; offset++; } } } break; } return(offset); }
public Protobuf(JsonNode_Object encodeProtos, JsonNode_Object decodeProtos) { this.encoder = new MsgEncoder(encodeProtos); this.decoder = new MsgDecoder(decodeProtos); }
public byte[] encode(string route, JsonNode_Object msg) { return(encoder.encode(route, msg)); }
public void notify(string route, JsonNode_Object msg) { protocol.send(route, msg); }
public void connect(JsonNode_Object user) { connect(user, null); }
public byte[] encode(string route, uint id, JsonNode_Object msg) { int routeLength = byteLength(route); if (routeLength > MSG_Route_Limit) { throw new Exception("Route is too long!"); } //Encode head //The maximus length of head is 1 byte flag + 4 bytes message id + route string length + 1byte byte[] head = new byte[routeLength + 6]; int offset = 1; byte flag = 0; if (id > 0) { byte[] bytes = Protobuf.Encoder.encodeUInt32(id); writeBytes(bytes, offset, head); flag |= ((byte)MessageType.MSG_REQUEST) << 1; offset += bytes.Length; } else { flag |= ((byte)MessageType.MSG_NOTIFY) << 1; } //Compress head if (dict.ContainsKey(route)) { ushort cmpRoute = dict[route]; writeShort(offset, cmpRoute, head); flag |= MSG_Route_Mask; offset += 2; } else { //Write route length head[offset++] = (byte)routeLength; //Write route writeBytes(Encoding.UTF8.GetBytes(route), offset, head); offset += routeLength; } head[0] = flag; //Encode body byte[] body; if (encodeProtos.ContainsKey(route)) { body = protobuf.encode(route, msg); } else { body = Encoding.UTF8.GetBytes(msg.ToString()); } //Construct the result byte[] result = new byte[offset + body.Length]; for (int i = 0; i < offset; i++) { result[i] = head[i]; } for (int i = 0; i < body.Length; i++) { result[offset + i] = body[i]; } //Add id to route map if (id > 0) { reqMap.Add(id, route); } return(result); }
/// <summary> /// Encode the array type. /// </summary> private int encodeArray(IList <IJsonNode> msg, JsonNode_Object value, int offset, byte[] buffer, JsonNode_Object proto) { IJsonNode value_type, value_tag; if (value.TryGetValue("type", out value_type) && value.TryGetValue("tag", out value_tag)) { if (this.util.isSimpleType(value_type.ToString())) { offset = this.writeBytes(buffer, offset, this.encodeTag(value_type.ToString(), Convert.ToInt32(value_tag.AsInt()))); offset = this.writeBytes(buffer, offset, Encoder.encodeUInt32((uint)msg.Count)); foreach (var item in msg) { offset = this.encodeProp(item, value_type.ToString(), offset, buffer, null); } } else { foreach (var item in msg) { offset = this.writeBytes(buffer, offset, this.encodeTag(value_type.ToString(), Convert.ToInt32(value_tag.AsInt()))); offset = this.encodeProp(item, value_type.ToString(), offset, buffer, proto); } } } return(offset); }
/// <summary> /// Check the message. /// </summary> private bool checkMsg(JsonNode_Object msg, JsonNode_Object proto) { ICollection <string> protoKeys = proto.Keys; foreach (string key in protoKeys) { JsonNode_Object value = (JsonNode_Object)proto[key]; IJsonNode proto_option; if (value.TryGetValue("option", out proto_option)) { switch (proto_option.ToString()) { case "required": if (!msg.ContainsKey(key)) { return(false); } else { } break; case "optional": IJsonNode value_type; JsonNode_Object messages = (JsonNode_Object)proto["__messages"]; value_type = value["type"]; if (msg.ContainsKey(key)) { IJsonNode value_proto; if (messages.TryGetValue(value_type.ToString(), out value_proto) || protos.TryGetValue("message " + value_type.ToString(), out value_proto)) { checkMsg((JsonNode_Object)msg[key], (JsonNode_Object)value_proto); } } break; case "repeated": IJsonNode msg_name; IJsonNode msg_type; if (value.TryGetValue("type", out value_type) && msg.TryGetValue(key, out msg_name)) { if (((JsonNode_Object)proto["__messages"]).TryGetValue(value_type.ToString(), out msg_type) || protos.TryGetValue("message " + value_type.ToString(), out msg_type)) { for (int i = 0; i < msg_name.GetListCount(); i++) { IJsonNode item = msg_name.GetArrayItem(i); if (!checkMsg((JsonNode_Object)item, (JsonNode_Object)msg_type)) { return(false); } } } } break; } } } return(true); }
public RequestMessage(string route, JsonNode_Object msg, Action <JsonNode_Object> action) { this.route = route; this.msg = msg; this.action = action; }