/// <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);
    }
Пример #2
0
    /// <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 null.");
            return(null);
        }

        if (packetImpl.PacketType != PacketType.ClientToServer)
        {
            Log.Warning("Packet type is invalid.");
            return(null);
        }

        // 恐怖的 GCAlloc,这里是例子,不做优化
        using (MemoryStream stream = new MemoryStream())
        {
            //跳过消息头长度(8)的位置开始序列化消息内容
            stream.Position = PacketHeaderLength;
            Serializer.SerializeWithLengthPrefix <T>(stream, packet, PrefixStyle.Fixed32);

            //回头再来序列化消息包头
            stream.Position = 0;
            CSPacketHeader header = ReferencePool.Acquire <CSPacketHeader>();
            header.Id           = packet.Id;
            header.PacketLength = (int)stream.Length - PacketHeaderLength;

            //Log.Info("序列化的id:" + header.Id);
            //Log.Info("序列化的包体长度:" + header.PacketLength);

            //方式1:直接写入字节数据id+packetLen
            stream.Write(BitConverter.GetBytes(header.Id), 0, 4);
            stream.Write(BitConverter.GetBytes(header.PacketLength), 0, 4);
            //方式2:用头部结构体序列化进去(暂时没测通过)
            //Serializer.SerializeWithLengthPrefix(stream, header, PrefixStyle.Fixed32);
            ReferencePool.Release <CSPacketHeader>(header);

            return(stream.ToArray());
        }
    }