==>>点击查看本系列文章目录

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 工厂模式

抽象接口  工厂负责创建编码器和解码器

1.工厂

    /// <summary>
/// 一个抽象的传输消息编解码器工厂。
/// </summary>
public interface ITransportMessageCodecFactory
{
/// <summary>
/// 获取编码器。
/// </summary>
/// <returns>编码器实例。</returns>
ITransportMessageEncoder GetEncoder(); /// <summary>
/// 获取解码器。
/// </summary>
/// <returns>解码器实例。</returns>
ITransportMessageDecoder GetDecoder();
}

2.编码器

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

3.解码器

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

实现类  工厂、编码器、解码器为MessagePack的实现

1.工厂

   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
}

2.编码器

    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
}

3.解码器

    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; }
}

由于MessagePack序列化方式具有侵入性,需要添加 MessagePackObjectAttribute 和 KeyAttribute 特性,因此需要对 TransportMessage 做装饰:

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()]
public string Id
{
get { return _transportMessage.Id; }
set { _transportMessage.Id = value; }
} /// <summary>
/// 消息内容。
/// </summary>
[Key()]
public object Content
{
get { return _transportMessage.Content; }
set { _transportMessage.Content = value; }
} /// <summary>
/// 内容类型。
/// </summary>
[Key()]
public string ContentType
{
get { return _transportMessage.ContentType; }
set { _transportMessage.ContentType = value; }
}
}

2.3 依赖注入

Autofac 是一个依赖注入工具包,比.net Core 原始的依赖注入拥有更完善的功能,中文官方文档:https://autofaccn.readthedocs.io/zh/latest/index.html

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 =
};
TransportMessage transportMessage = new TransportMessage
{
Id = "",
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, "");
Assert.AreEqual(message.ContentType, "Person");
Assert.AreEqual(((object[])message.Content)[].ToString(), "张宏伟" );
Assert.AreEqual(((object[])message.Content)[].ToString(), "");
} [MessagePackObject]
public class Person
{
[Key()]
public string Name { get; set; }
[Key()]
public int Age { get; set; }
}
}

(六)分布式通信----MessagePack序列化的更多相关文章

  1. CRL快速开发框架系列教程六(分布式缓存解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  2. Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

    酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...

  3. spring boot / cloud (十六) 分布式ID生成服务

    spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...

  4. axis实现webservices分布式通信

    分布式通信原理 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2ZsMjAxMjEzMTQ=/font/5a6L5L2T/fontsize/400/fil ...

  5. 10.axis实现webservices分布式通信

    转自:https://www.aliyun.com/jiaocheng/310112.html 分布式通信原理 基本原理:stub和skeleton作为客户端和服务端传输的中介,stub和skelet ...

  6. dotnet 使用 MessagePack 序列化对象

    和很多序列化库一样,可以通过 MessagePack 序列化和反序列化,和 json 相比这个库提供了二进制的序列化,序列化之后的内容长度比 json 小很多 这个库能序列的内容不多,大多数时候建议使 ...

  7. 4.7 ROS分布式通信

    4.7 ROS分布式通信 ROS是一个分布式计算环境.一个运行中的ROS系统可以包含分布在多台计算机上多个节点.根据系统的配置方式,任何节点可能随时需要与任何其他节点进行通信. 因此,ROS对网络配置 ...

  8. SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能

    It's like JSON.but fast and small. MessagePack is an efficient binary serialization format. It lets ...

  9. (七)分布式通信----Netty实现NIO通信

    目录 1. 消息监听器 2. 指令执行器 3. 消息发送器 4. 客户端工厂 5. 序列化工具 6. 通信主机 项目文件结构图 通信主机: 1. 消息监听器(黄色框) 这部分由 Netty 实现,Ne ...

随机推荐

  1. nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现

    nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现 一.漏洞描述 这个漏洞其实和代码执行没有太大的关系,主要原因是错误地解析了请求的URL,错误地获取到用户请求的文件名,导致出现权限绕过.代 ...

  2. docker学习ppt

    保存下学习资料

  3. [系列] Go gRPC Hello World

    目录 概述 四类服务方法 安装 写个 Hello World 服务 推荐阅读 概述 开始 gRPC 了,这篇文章学习使用 gRPC,输出一个 Hello World. 用 Go 实现 gRPC 的服务 ...

  4. html5教程 《实用技巧》—让你的网站变成响应式的3个简单步骤

    如今,一个网站只在桌面屏幕上好看是远远不够的,同时也要在平板电脑和智能手机中能够良好呈现.响应式的网站是指它能够适应客户端的屏幕尺寸,自动响应客户端尺寸变化.在这篇文章中,我将向您展示如何通过3个简单 ...

  5. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

  6. SpringBoot入门(二):日志及自定义属性

    这一章主要说springboot中日志的配置.自定义属性的配置与读取.分环境的yml配置文件(如本地环境.测试环境.生产环境等).比较偏向实际开发,较为实用,前面一章的一些基本创建在这里就不多废话了. ...

  7. 使用vsftp与shell实现对进程与服务状态的监控

    先说一下需求吧,公司开发了一款新的产品,新产品嘛,有着不得不出问题的理由,四个云机房,总共三百余台机器,需要实时的监控进程状态,虽然有zabbix来实现,但领导需求是脚本和zabbix一起做,zabb ...

  8. Git 从master拉取代码创建新分支

    从master拉取新分支并push到远端 开发过程中经常用到从master分支copy一个开发分支: 1.切换到被copy的分支(master),并且从远端拉取最新版本 $git checkout m ...

  9. linux文本编辑vim命令

    1.Vim Vim  是一个功能强大的全屏幕文本编辑器,是 Linux/UNIX 上最常用的文本编辑器,它的作用是建立.编辑.显示文本文件. Vim 没有菜单,只有命令 2.Vim 工作模式 3.插入 ...

  10. kube-scheduler源码分析

    kubernetes集群三步安装 kube-scheduler源码分析 关于源码编译 我嫌弃官方提供的编译脚本太麻烦,所以用了更简单粗暴的方式编译k8s代码,当然官方脚本在编译所有项目或者夸平台编译以 ...