当前位置: 移动技术网 > IT编程>开发语言>.net > (一)ASP.Net Core 分布式通信----序列化

(一)ASP.Net Core 分布式通信----序列化

2019年08月04日  | 移动技术网IT编程  | 我要评论

景公出游于寒途,摇情乐园,马航失联1个月

1. .net core的序列化方式

1.1 json.net

常用的工具包,如newtonsoft.json, 它是基于json格式的序列化和反序列化的组件

json.net 有以下优点:

       侵入性:可以不添加attribute,就能进行序列化操作

       灵活性:可以灵活性配置,比如允许被序列化的成员自定义名字,屏蔽的非序列化属性成员

       可读性: 数据格式比较简单, 易于读写

       依赖性:可以序列化成jobject,无需依赖对象进行序列化和泛型化。

1.2 protobuf

它是基于二进制格式的序列化和反序列化的组件

protobuf 有以下优点:

     性能高 : 序列化后体积相比json和xml很小,适合rpc二进制传输
   跨语言:支持跨平台多语言
        兼容性:消息格式升级和兼容性还不错
        速度快 :序列化反序列化速度很快,快于json的处理速度

1.3 messagepack

它是基于二进制格式的序列化和反序列化的组件

messagepack有以下优点:

      性能高:序列化后体积相比json和xml很小,适合rpc二进制传输
   跨语言:支持跨平台多语言
        兼容性:消息格式升级和兼容性还不错
        速度快 :序列化反序列化速度很快,快于json的处理速度

messagepack不管是小数据量还是大数据量都保持比较稳定的性能,本文中使用messagepack序列化方式。

2. 项目编码及设计模式

 如下是文件结构:

 

2.1 工厂模式

抽象类

    /// <summary>
    /// 一个抽象的传输消息编解码器工厂。
    /// </summary>
    public interface itransportmessagecodecfactory
    {
        /// <summary>
        /// 获取编码器。
        /// </summary>
        /// <returns>编码器实例。</returns>
        itransportmessageencoder getencoder();

        /// <summary>
        /// 获取解码器。
        /// </summary>
        /// <returns>解码器实例。</returns>
        itransportmessagedecoder getdecoder();
    }

 

    /// <summary>
    /// 编码器
    /// </summary>
    public interface itransportmessageencoder
    {
        byte[] encode(transportmessage message);
    }

 

    /// <summary>
    /// 解码器
    /// </summary>
    public interface itransportmessagedecoder
    {
        transportmessage decode(byte[] data);
    }

 

实现类

   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>
        /// 获取编码器 
        /// </summary>
        /// <returns></returns>
        public itransportmessageencoder getencoder()
        {
            return _transportmessageencoder;
        }

        /// <inheritdoc />
        /// <summary>
        /// 获取解码器 
        /// </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 装饰器模式

    public class transportmessage
    {
        /// <summary>
        /// 消息id。
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// 消息内容。
        /// </summary>
        public object content { get; set; }

        /// <summary>
        /// 内容类型。
        /// </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>
        /// 消息id。
        /// </summary>
        [key(0)]
        public string id
        {
            get { return _transportmessage.id; }
            set { _transportmessage.id = value; }
        }

        /// <summary>
        /// 消息内容。
        /// </summary>
        [key(1)]
        public object content
        {
            get { return _transportmessage.content; }
            set { _transportmessage.content = value; }
        }

        /// <summary>
        /// 内容类型。
        /// </summary>
        [key(2)]
        public string contenttype
        {
            get { return _transportmessage.contenttype; }
            set { _transportmessage.contenttype = value; }
        }
    }

 

2.3 依赖注入

 

using autofac;

    public static class containerbuilderextensions
    {
        /// <summary>
        /// 使用messagepack编码解码方式
        /// </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 单元测试

using messagepack;
using microsoft.visualstudio.testtools.unittesting;

    [testclass]
    public class messagepacktest
    {
        [testmethod]
        public void testcodec()
        {
            person person = new person
            {
                name = "张宏伟",
                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(), "张宏伟" );
            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; }
        }
    }

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网