/// <summary> /// 序列化消息包。 /// </summary> /// <typeparam name="T">消息包类型。</typeparam> /// <param name="packet">要序列化的消息包。</param> /// <returns>序列化后的消息包字节流。</returns> public byte[] Serialize <T>(T packet) where T : Packet { PacketBase packetImpl = packet as PacketBase; if (packetImpl == null) { Log.Warning("Packet is invalid."); return(null); } if (packetImpl.PacketType != PacketType.ClientToServer) { Log.Warning("Send packet invalid."); return(null); } // 恐怖的 GCAlloc,这里是例子,不做优化 using (MemoryStream memoryStream = new MemoryStream()) { CSPacketHeader packetHeader = new CSPacketHeader(packetImpl.PacketId); Serializer.Serialize(memoryStream, packetHeader); Serializer.SerializeWithLengthPrefix(memoryStream, packet, PrefixStyle.Fixed32); return(memoryStream.ToArray()); } }
/// <summary> /// 序列化消息包。 /// </summary> /// <typeparam name="T">消息包类型。</typeparam> /// <param name="packet">要序列化的消息包。</param> /// <param name="destination">要序列化的目标流。</param> /// <returns>是否序列化成功。</returns> public bool Serialize <T>(T packet, Stream destination) where T : Packet { PacketBase packetImpl = packet as PacketBase; if (packetImpl == null) { Log.Warning("Packet is invalid."); return(false); } if (packetImpl.PacketType != PacketType.ClientToServer) { Log.Warning("Send packet invalid."); return(false); } m_CachedStream.SetLength(m_CachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入 m_CachedStream.Position = 0L; CSPacketHeader packetHeader = ReferencePool.Acquire <CSPacketHeader>(); Serializer.Serialize(m_CachedStream, packetHeader); ReferencePool.Release(packetHeader); Serializer.SerializeWithLengthPrefix(m_CachedStream, packet, PrefixStyle.Fixed32); ReferencePool.Release((IReference)packet); m_CachedStream.WriteTo(destination); return(true); }
/// <summary> /// 序列化消息包。 /// </summary> /// <typeparam name="T">消息包类型。</typeparam> /// <param name="packet">要序列化的消息包。</param> public bool Serialize <T> (T packet, Stream destination) where T : Packet { PacketBase packetImpl = packet as PacketBase; if (packetImpl == null) { Log.Warning("Packet is invalid."); return(false); } if (packetImpl.PacketType != PacketType.ClientToServer) { Log.Warning("Send packet invalid."); return(false); } /* 以下内容为木头本人做的改动,不知道是否有错误的地方(虽然它运行起来是正确的),希望大家能帮忙指正 */ // 因为头部消息有8字节长度,所以先跳过8字节 destination.Position = 8; Serializer.SerializeWithLengthPrefix(destination, packet, PrefixStyle.Fixed32); // 头部消息 CSPacketHeader packetHeader = ReferencePool.Acquire <CSPacketHeader>(); packetHeader.Id = packet.Id; packetHeader.PacketLength = (int)destination.Length - 8; // 消息内容长度需要减去头部消息长度 destination.Position = 0; Serializer.SerializeWithLengthPrefix(destination, packetHeader, PrefixStyle.Fixed32); ReferencePool.Release(packetHeader); return(true); }
/// <summary> /// 序列化消息包。 /// </summary> /// <typeparam name="T">消息包类型。</typeparam> /// <param name="packet">要序列化的消息包。</param> /// <returns>序列化后的消息包字节流。</returns> public byte[] Serialize <T> (T packet) where T : Packet { PacketBase packetImpl = packet as PacketBase; if (packetImpl == null) { Log.Warning("Packet is invalid."); return(null); } if (packetImpl.PacketType != PacketType.ClientToServer) { Log.Warning("Send packet invalid."); return(null); } // 恐怖的 GCAlloc,这里是例子,不做优化(这句注释是框架作者写的,我本人并不懂GC什么的) using (MemoryStream memoryStream = new MemoryStream()) { /* 以下内容为木头本人做的改动,不知道是否有错误的地方(虽然它运行起来是正确的),希望大家能帮忙指正 */ // 因为头部消息有8字节长度,所以先跳过8字节 memoryStream.Position = 8; Serializer.SerializeWithLengthPrefix(memoryStream, packet, PrefixStyle.Fixed32); // 头部消息 CSPacketHeader packetHeader = ReferencePool.Acquire <CSPacketHeader> (); packetHeader.Id = packet.Id; packetHeader.PacketLength = (int)memoryStream.Length - 8; // 消息内容长度需要减去头部消息长度 memoryStream.Position = 0; Serializer.SerializeWithLengthPrefix(memoryStream, packetHeader, PrefixStyle.Fixed32); ReferencePool.Release(packetHeader); return(memoryStream.ToArray()); } }