ASP.Net Core Distributed Communication--Serialization

Posted by railanc4309 on Sun, 04 Aug 2019 16:42:42 +0200

1. Serialization of Net Core

1.1 json.Net

Common toolkits, such as Newtonsoft.Json, are components of serialization and deserialization based on json format

json.net has the following advantages:

Intrusivity: Serialization can be done without adding attribute s

Flexibility: Flexible configurations, such as allowing serialized members to customize names and masking non-serialized attribute members

Readability: Data format is simple and easy to read and write

Dependency: You can serialize to JObject without relying on objects for serialization and generics.

1.2 protobuf

It is a component of serialization and deserialization based on binary format

protobuf has the following advantages:

High performance: Serialized volume is smaller than Json and XML, suitable for RPC binary transmission
Cross-Language: Support for Cross-Platform Multilingualism
Compatibility: Message format upgrades and compatibility are good
Fast: Serialization deserialization is faster than Json's processing speed

1.3 messagepack

It is a component of serialization and deserialization based on binary format

messagepack has the following advantages:

High performance: Serialized volume is smaller than Json and XML, suitable for RPC binary transmission
Cross-Language: Support for Cross-Platform Multilingualism
Compatibility: Message format upgrades and compatibility are good
Fast: Serialization deserialization is faster than Json's processing speed

Message pack maintains stable performance in both small and large data volumes. In this paper, message pack serialization is used.

2. Project Coding and Design Patterns

The following is the file structure:

 

2.1 Factory Model

abstract class

    /// <summary>
    /// An abstract factory for transmitting message codec.
    /// </summary>
    public interface ITransportMessageCodecFactory
    {
        /// <summary>
        /// Get the encoder.
        /// </summary>
        /// <returns>Encoder example.</returns>
        ITransportMessageEncoder GetEncoder();

        /// <summary>
        /// Get the decoder.
        /// </summary>
        /// <returns>Examples of decoders.</returns>
        ITransportMessageDecoder GetDecoder();
    }

 

    /// <summary>
    /// Encoder
    /// </summary>
    public interface ITransportMessageEncoder
    {
        byte[] Encode(TransportMessage message);
    }

 

    /// <summary>
    /// Decoder
    /// </summary>
    public interface ITransportMessageDecoder
    {
        TransportMessage Decode(byte[] data);
    }

 

Implementation class

   public sealed class MessagePackTransportMessageCodecFactory : ITransportMessageCodecFactory
    {
        #region Field
        private readonly ITransportMessageEncoder _transportMessageEncoder = new MessagePackTransportMessageEncoder();
        private readonly ITransportMessageDecoder _transportMessageDecoder = new MessagePackTransportMessageDecoder();
        #endregion Field

        #region Implementation of ITransportMessageCodecFactory

        /// <inheritdoc />
        /// <summary>
        /// Acquisition coder 
        /// </summary>
        /// <returns></returns>
        public ITransportMessageEncoder GetEncoder()
        {
            return _transportMessageEncoder;
        }

        /// <inheritdoc />
        /// <summary>
        /// Acquisition decoder 
        /// </summary>
        /// <returns></returns>
        public ITransportMessageDecoder GetDecoder()
        {
            return _transportMessageDecoder;
        }
        #endregion Implementation of ITransportMessageCodecFactory
    }

 

    public sealed class MessagePackTransportMessageEncoder : ITransportMessageEncoder
    {
        #region Implementation of ITransportMessageEncoder

        public byte[] Encode(TransportMessage transportMessage)
        {
            MessagePackTransportMessage messagePackTransportMessage = new MessagePackTransportMessage(transportMessage);
            return MessagePackSerializer.Serialize(messagePackTransportMessage);
        }
        
        #endregion Implementation of ITransportMessageEncoder
    }

 

    public sealed class MessagePackTransportMessageDecoder : ITransportMessageDecoder
    {
        #region Implementation of ITransportMessageDecoder

        public TransportMessage Decode(byte[] data)
        {
            MessagePackTransportMessage messagePackTransportMessage = MessagePackSerializer.Deserialize<MessagePackTransportMessage>(data);
            return messagePackTransportMessage.GetTransportMessage();
        }

        #endregion Implementation of ITransportMessageDecoder
    }

 

2.2 Decorator Model

    public class TransportMessage
    {
        /// <summary>
        /// news Id. 
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Message content.
        /// </summary>
        public object Content { get; set; }

        /// <summary>
        /// Content type.
        /// </summary>
        public string ContentType { get; set; }
    }

 

using MessagePack;

    [MessagePackObject]
    public class MessagePackTransportMessage
    {
        private TransportMessage _transportMessage;
        public MessagePackTransportMessage(): this(new TransportMessage())
        {
        }

        public MessagePackTransportMessage(TransportMessage transportMessage)
        {
            this._transportMessage = transportMessage;
        }

        public TransportMessage GetTransportMessage()
        {
            return _transportMessage;
        }
        /// <summary>
        /// news Id. 
        /// </summary>
        [Key(0)]
        public string Id
        {
            get { return _transportMessage.Id; }
            set { _transportMessage.Id = value; }
        }

        /// <summary>
        /// Message content.
        /// </summary>
        [Key(1)]
        public object Content
        {
            get { return _transportMessage.Content; }
            set { _transportMessage.Content = value; }
        }

        /// <summary>
        /// Content type.
        /// </summary>
        [Key(2)]
        public string ContentType
        {
            get { return _transportMessage.ContentType; }
            set { _transportMessage.ContentType = value; }
        }
    }

 

2.3 Dependency Injection

 

using Autofac;

    public static class ContainerBuilderExtensions
    {
        /// <summary>
        /// Use messagepack Coding and Decoding Method
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static ContainerBuilder UseMessagePackCodec(this ContainerBuilder builder)
        {
            builder.RegisterType(typeof(MessagePackTransportMessageCodecFactory)).As(typeof(ITransportMessageCodecFactory)).SingleInstance();
            return builder;
        }
    }

 

2.4 Unit Testing

using MessagePack;
using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class MessagePackTest
    {
        [TestMethod]
        public void TestCodec()
        {
            Person person = new Person
            {
                Name = "Zhang Hongwei",
                Age = 18
            };
            TransportMessage transportMessage = new TransportMessage
            {
                Id = "1",
                ContentType = "Person",
                Content = person
            };
            MessagePackTransportMessageCodecFactory factory = new MessagePackTransportMessageCodecFactory();
            ITransportMessageEncoder encoder = factory.GetEncoder();
            ITransportMessageDecoder decoder = factory.GetDecoder();
            byte[] vs = encoder.Encode(transportMessage);
            TransportMessage message =decoder.Decode(vs);
            Assert.AreEqual(message.Id, "1");
            Assert.AreEqual(message.ContentType, "Person");
            Assert.AreEqual(((object[])message.Content)[0].ToString(), "Zhang Hongwei" );
            Assert.AreEqual(((object[])message.Content)[1].ToString(), "18");
        }

        [MessagePackObject]
        public class Person
        {
            [Key(0)]
            public string Name { get; set; }
            [Key(1)]
            public int Age { get; set; }
        }
    }

Topics: PHP JSON Attribute xml codec