Skip to content

数据包解释

Henry edited this page Oct 11, 2019 · 1 revision

在通讯应用中,往往需要把网络数据解释成对象或对象序列化到网络数据中;组件制定了这样一个规则来让使用者扩展相关功能。

Server IPacket

    public interface IPacket : IDisposable
    {

        EventHandler<EventArgs.PacketDecodeCompletedEventArgs> Completed
        {
            get; set;
        }

        IPacket Clone();

        void Decode(ISession session, System.IO.Stream stream);

        void Encode(object data, ISession session, System.IO.Stream stream);

        byte[] Encode(object data, IServer server);

        ArraySegment<byte> Encode(object data, IServer server, byte[] buffer);
    }

Client IPacket

    public interface IClientPacket : IDisposable
    {

        EventClientPacketCompleted Completed
        {
            get;
            set;
        }

        IClientPacket Clone();

        void Decode(IClient client, System.IO.Stream stream);

        void Encode(object data, IClient client, System.IO.Stream stream);
    }

消息规则

image

Decoe的Protobuf实现

        protected override object OnReader(ISession session, PipeStream reader)
        {
            Type type = TypeHeader.ReadType(reader);
            int bodySize = reader.ReadInt32();
            return ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(reader, null,type,bodySize);
        }

        public void Decode(ISession session, System.IO.Stream stream)
        {
            PipeStream pstream = stream.ToPipeStream();
        START:
            object data;
            if (mSize == 0)
            {        
                    if (pstream.Length < 4)
                        return;
                    mSize = pstream.ReadInt32();
            }
            if (pstream.Length < mSize)
                return;
            data = OnReader(session, pstream);
            mSize = 0;
            Completed?.Invoke(this, mCompletedArgs.SetInfo(session, data));
            goto START;
        }

Encode的Protobuf实现

        protected override void OnWrite(ISession session, object data, PipeStream writer)
        {
            TypeHeader.WriteType(data, writer);
            MemoryBlockCollection bodysize = writer.Allocate(4);
            int bodyStartlegnth = (int)writer.CacheLength;
            ProtoBuf.Meta.RuntimeTypeModel.Default.Serialize(writer, data);
            bodysize.Full((int)writer.CacheLength - bodyStartlegnth);
        }

        private void OnEncode(ISession session, object data, System.IO.Stream stream)
        {
            PipeStream pstream = stream.ToPipeStream();
            MemoryBlockCollection msgsize = pstream.Allocate(4);
            int length = (int)pstream.CacheLength;
            OnWrite(session, data, pstream);
            msgsize.Full((int)pstream.CacheLength - length);
        }

使用解释器

  • Server
 mServer = SocketFactory.CreateTcpServer<Program, Packet>();
  • Client
SocketFactory.CreateClient<ClientPacket>(packet, "127.0.0.1", 9090);