(六)分布式通信----MessagePack序列化
==>>点击查看本系列文章目录
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序列化的更多相关文章
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable
酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...
- spring boot / cloud (十六) 分布式ID生成服务
spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...
- axis实现webservices分布式通信
分布式通信原理 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2ZsMjAxMjEzMTQ=/font/5a6L5L2T/fontsize/400/fil ...
- 10.axis实现webservices分布式通信
转自:https://www.aliyun.com/jiaocheng/310112.html 分布式通信原理 基本原理:stub和skeleton作为客户端和服务端传输的中介,stub和skelet ...
- dotnet 使用 MessagePack 序列化对象
和很多序列化库一样,可以通过 MessagePack 序列化和反序列化,和 json 相比这个库提供了二进制的序列化,序列化之后的内容长度比 json 小很多 这个库能序列的内容不多,大多数时候建议使 ...
- 4.7 ROS分布式通信
4.7 ROS分布式通信 ROS是一个分布式计算环境.一个运行中的ROS系统可以包含分布在多台计算机上多个节点.根据系统的配置方式,任何节点可能随时需要与任何其他节点进行通信. 因此,ROS对网络配置 ...
- SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
It's like JSON.but fast and small. MessagePack is an efficient binary serialization format. It lets ...
- (七)分布式通信----Netty实现NIO通信
目录 1. 消息监听器 2. 指令执行器 3. 消息发送器 4. 客户端工厂 5. 序列化工具 6. 通信主机 项目文件结构图 通信主机: 1. 消息监听器(黄色框) 这部分由 Netty 实现,Ne ...
随机推荐
- spark 源码分析之十九 -- Stage的提交
引言 上篇 spark 源码分析之十九 -- DAG的生成和Stage的划分 中,主要介绍了下图中的前两个阶段DAG的构建和Stage的划分. 本篇文章主要剖析,Stage是如何提交的. rdd的依赖 ...
- 使用jquery删除链接所在的行
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 【Arduino】37种传感器系列实验(4)---振动传感器模块
---恢复内容开始--- 37款传感器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器,依照实践(动手试试)出真知的理念,以学习和交流为 ...
- PLSQL连接数据库报监听程序找不到符合协议堆
服务器上某个数据库出现' ORA-12516: TNS: 监听程序找不到符合协议堆栈要求的可用处理程'错误,要解决该问题首先查看一下数据库现有的进程数,是否已经达到参数processes的大小 根 ...
- hdoj 1753 (Java)
刚刚开始用Java,代码难免不够简洁. import java.math.BigDecimal; import java.util.Scanner; public class Main { publi ...
- RGB颜色 三者都是0为黑色而255是白色 解释
问题: RGB颜色 都是0为黑色而255是白色 与日常生活的黑色白色差距怎么那么大,(与物理学中的黑色吸收光是否相悖)而且为什么要这样定义呢? 链接:https://www.zhihu.com/que ...
- maven项目引用错误 和项目结构问题
解决办法: 鼠标右键 maven ---->update prroject Configuration 然后 maven clean maven install
- GridLayout and GridData
GridLayout的风格 GridLayout类提供了GridLayout 布局中划分网格的信息,主要通过以下几个参数进行设置. 属性: NumColumns:通过“gridLayout.numCo ...
- x32下PsSetLoadImageNotifyRoutine的逆向
一丶简介 纯属兴趣爱好.特来逆向玩玩. PsSetLoadImageNotifyRoutine 是内核中用来监控模块加载.操作系统给我们提供的回调. 我们只需要填写对应的回调函数原型即可进行加监控. ...
- Java性能调优的11个实用技巧
译文出处: ITeye 原文出处:dzone 大多数开发人员认为性能优化是个比较复杂的问题,需要大量的经验和知识.是的,这并不没有错.诚然,优化应用程序以获得最好的性能并不是一件容易的事情,但这 ...