/// <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();
        }