net-core-30-Signalr-03-使用MessagePack压缩传输内容

3次阅读

共计 2796 个字符,预计需要花费 7 分钟才能阅读完成。

MessagePack 基础介绍

Signalr 默认使用的是 json 形式传递数据,但是 signalr 提供了灵活的扩展,支持 MessagePack 形式序列化数据,以增加性能降低网络传输的效果,极大的提高响应速度。

先看一个 MessagePack 自定义序列化的例子, 以一个自定义的实体对象为例,可以使用 MessagepackObject 标记为序列化的对象,同时定义使用属性名作为 key(区分大小写),同时可以定义忽略某个属性等、以及自定义 key 等

  [MessagePackObject(keyAsPropertyName: true)]
  public class OffLineData
  {
      /// <summary>
      /// 用户 Id
      /// </summary>
      public string UserId {set; get;}
      /// <summary>
      /// 连接 Id
      /// </summary>
      public string ConnectionId {set; get;}
      /// <summary>
      /// 是否该用户的最后一个连接
      /// </summary>
      public bool IsLast {set; get;}
      [IgnoreMember]
      public string Test {set;get;}
  }

  // 比如对象,new OffLineData(){UserId="1000",ConnectionId="AZDEFASDFASDF",IsLast:true}通过 MessagePack 序列化后应该会是{UserId:"1000",ConnectionId:"AZDEFASDFASDF",IsLast:true}, 这个跟常用的 json 基本相同

同时 MessagePack 还可以定义序列化成数组形式,代码如下

  [MessagePackObject]
  public class OffLineData
    {
        /// <summary>
        /// 用户 Id
        /// </summary>
        [Key(0)]
        public string UserId {set; get;}
        /// <summary>
        /// 连接 Id
        /// </summary>
        [Key(0)]
        public string ConnectionId {set; get;}
        /// <summary>
        /// 是否该用户的最后一个连接
        /// </summary>
        [Key(0)]
        public bool IsLast {set; get;}
    }

  // 比如对象,new OffLineData(){UserId="1000",ConnectionId="AZDEFASDFASDF",IsLast:true}通过 MessagePack 序列化后应该会是["10000","AZDEFASDFASDF",true]

更多 MessagePack 的内容可以自行结尾的文档,此处不再过多介绍.

为 Signalr 添加 MessagePack 支持

  • 引入需要的 Nuget 包

Microsoft.AspNetCore.SignalR.Protocols.MessagePack

  • 修改之前的 ConfigureServices

      // 添加 Signalr
      services.AddSignalR(config =>
      {if (_webEnv.IsDevelopment())
          {config.EnableDetailedErrors = true;}
      })
      // 支持 MessagePack
      .AddMessagePackProtocol();
  • 前端引入 messagepack 解析库

由于 MessagePack 传输是以二进制形式进行传输,降低了带宽,但是同时也增加到了代码的复杂度,原本直接获取数据就可以用的,现在需要先将二进制数据转换成正常数据,好在官方提供了对应的 js 库 msgpack5signalr-protocol-msgpack
可以通过 vs 的包管理工具或者 npm 安装,然后拷贝需要的文件到项目的 lib 文件夹, 比如我的结构是

  signalr-protocol-msgpack
  |-msgpack5.js
  |-msgpack5.min.js
  |-signalr-protocol-msgpack.js
  |-signalr-protocol-msgpack.min.js

前端页面引入这两个 js(注意顺序:signalr、msgpack5、signalr-protocol-msgpack)

  • 修改 js 连接对象,支持上 MessagePack

    new signalR.HubConnectionBuilder()
      .configureLogging(signalR.LogLevel.Error) // 前端控制台的日志级别,根据需要配置
      .withUrl('http://localhost:50001/notify-hub') // 连接地址, 这个地址是 signalr 项目的地址
      .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol()) // 使用 Messagepack 来解析推送的数据
      .withAutomaticReconnect([0, 2000, 5000, 10000, 20000]) // 配置重连的时间
      .build();
    
      // 重连的时候触发
      connection.onreconnecting(function (info) {console.info('----------------------------------signalr-- onreconnecting', info);
      });
    
      // 连接关闭的回调
      connection.onclose(function (err) {console.info('--------------------------------signalr-- onclose', err);
      });
    
      connection.start().then(function (data) {console.log('已成功连接到 signalr 服务器')
      }).catch(function (error) {console.error(error.toString());
      });
    

尚未解决问题

发现通过 json.net 序列化得到的对象,直接传递给 MessagePack 序列化会报错,没找着解决方法,直接改成字符串传递,然后在前端解析了,有遇到过的大佬欢迎指点下

至此,MessagePack 介绍算结束了,更多内容请通过快速导航查看下一篇

快速导航

标题 内容
索引 .net core 3.0 Signalr – 实现一个业务推送系统
上一篇 .net core 3.0 Signalr – 02 使用强类型的 Hub
下一篇 .net core 3.0 Signalr – 04 使用 Redis 做底板来支持横向扩展
源码地址 源码
官方文档 官方文档
MessagePack-CSharp MessagePack-CSharp
MessagePack MessagePack

正文完
 0