/// <summary> /// 主动向客户端通知 或者 回客户端消息, 先编码消息, 再编码长度 /// </summary> public void Send(Cmd cmd, IMessage message, Action <IMessage> callback = null) { if (!IsSocketValid()) { LogUtils.LogError("Socket is invalid!"); return; } /// CommonMessage编码 var comMsg = new CommonMessage { Cmd = cmd }; ProtoUtil.ReqCommonMsg(cmd, comMsg, message); NetPacket netPacket = new NetPacket(); netPacket.cmd = (int)cmd; netPacket.data = comMsg.ToByteArray(); if (callback != null) { Subscribe((int)cmd, callback); } //先编码消息, 再编码长度 byte[] byteArr = lengthEncode(messageEncode(netPacket)); Write(byteArr); }
/// <summary> /// 缓存中有数据进行处理, 先解码长度, 再解码消息 /// </summary> private void OnReceive() { //解码消息存储对象 byte[] buff = null; //当粘包解码器存在的时候,进行粘包处理 if (null != lengthDecode) { buff = lengthDecode(ref cache); //消息未接收全 退出数据处理 等待下次消息到达 if (null == buff) { m_bIsReading = false; return; } } else { //不用处理粘包 //缓存区中没有数据 直接跳出数据处理 等待消息到达 if (cache.Count == 0) { m_bIsReading = false; return; } buff = cache.ToArray(); cache.Clear(); } //反序列化方法是否存在 此方法必须存在 if (null == messageDecode) { throw new Exception("Message decode process is null"); } //进行消息反序列化 NetPacket packet = messageDecode(buff); //CommonMessage解码 var commonMsg = CommonMessage.Parser.ParseFrom(packet.data); var packetCmd = packet.cmd; IMessage clientReqMessage = ProtoUtil.ReqCommonMsg(commonMsg); //通知应用层,处理消息 handlerCenter.MessageReceive(this, packetCmd, clientReqMessage); //尾递归 防止在消息存储过程中 有其他消息到达而没有经过处理 OnReceive(); }