public async Task Send(ClientOutputBuffer buff) { //这里可以写一个发包统计 if (buff != null) { } else { Log.Error("PlayerContextBase::SendPackageImpl error buff ==null"); } var flag = await m_client.Send(buff); if (flag == false) { throw new Exception("发送消息失败"); } }
/// <summary> /// 将一个package消息打包到ClientOutputBuffer中 /// </summary> /// <param name="packageObj"></param> /// <returns></returns> public ClientOutputBuffer PackProtobufObject(object packageObj) { // 包检查 System.Diagnostics.Debug.Assert(packageObj != null, "PackProtobufObject error: packageObj is null"); // 获取一个固定长度的buff,作为存储包数据的缓冲 var bufferLen = Instance.m_globalConfigure.Global.Network.OutputBufferLen; var buffer = ClientOutputBuffer.LockSendBuffer(bufferLen); if (PackProtobufObjectInternal(packageObj, buffer)) { return(buffer); } Log.Error($"PackProtobufObject packageObj is too large for ClientOutputBuffer! package={packageObj.ToString()}"); ClientOutputBuffer.UnlockSendBuffer(buffer); return(null); // 组包失败,原因是package包长度太大,不能用一个ClientOutputBuffer打包 }
/// <summary> /// 打包并压缩单个包 /// </summary> /// <param name="packageObj"></param> /// <param name="buffer"></param> /// <param name="bufferOffest"></param> /// <returns></returns> public bool PackProtobufObjectInternal(object packageObj, ClientOutputBuffer buffer, int bufferOffest = 0) { System.Diagnostics.Debug.Assert(packageObj != null, "PackProtobufObjectInternal error: packageObj is null"); System.Diagnostics.Debug.Assert(buffer != null, "PackProtobufObjectInternal error: buffer is null"); // 包头的长度 const int headLen = sizeof(ushort) * 2; // 整个包的长度 ushort pkgLen; var dataOffset = bufferOffest; try { // 先将协议的内容写入到缓冲里 dataOffset += headLen; //int objDataStartIndex = dataOffset; // 记录在当前ms中有效数据起始index using (var stream = new MemoryStream(buffer.m_buffer, dataOffset, buffer.m_buffer.Length - dataOffset, true, true)) { // 先序列化协议包 m_messagePraser.SerializeTo(packageObj, stream); // 包长度 = 协议内容长度 + 包头长度 pkgLen = (ushort)(stream.Position + headLen); dataOffset += (int)stream.Position; } } catch (ArgumentOutOfRangeException) { return(false); } catch (ArgumentException) { return(false); } catch (NotSupportedException) { return(false); } // 再将包头的内容写入到缓冲里,包头内容包括是否是RPC消息、包长度和协议id,包长度在这里才能计算出来 using (var headerStream = new MemoryStream(buffer.m_buffer, bufferOffest, headLen)) { using (var writer = new BinaryWriter(headerStream)) { // 获取协议id ushort protocolId = (ushort)(OpcodeTypeDic.GetIdByType(packageObj.GetType())); //协议最高位为是否是Response ushort finalyProtocolId = (ushort)((packageObj is IResponse) ? (protocolId | 0x8000):(protocolId & 0x7FFF)); writer.Write(pkgLen); writer.Write(finalyProtocolId); // buff最后长度 buffer.m_dataLen = dataOffset; } } //MessageFactory.Recycle(packageObj as IMessage); return(true); }