(一)ASP.Net Core 分布式通信----序列化
程序员文章站
2022-05-18 15:20:51
1. .Net Core的序列化方式 1.1 json.Net 常用的工具包,如Newtonsoft.Json, 它是基于json格式的序列化和反序列化的组件 json.net 有以下优点: 侵入性:可以不添加attribute,就能进行序列化操作 灵活性:可以灵活性配置,比如允许被序列化的成员自定 ......
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; } } }
下一篇: 康熙最爱亲姐妹!康熙一共娶过几对姐妹花?
推荐阅读
-
ASP.NET Core MVC/API(一)
-
ASP.NET Core利用Jaeger实现分布式追踪详解
-
详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁
-
或许是你应该了解的一些 ASP.NET Core Web API 使用小技巧
-
Asp.Net Core + SignalR 实现实时通信
-
Visual Studio ASP.NET Core MVC入门教程第一篇
-
你所不知道的ASP.NET Core MVC/WebApi基础系列 (一)
-
ASP.NET Core利用Jaeger实现分布式追踪详解
-
详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁
-
ASP.NET Core MVC/API(一)