DeepSeek教unity------MessagePack-06
无类型 Typeless
无类型的 API 类似于 BinaryFormatter,因为它会将类型信息嵌入到数据块中,所以在调用 API 时不需要显式指定类型。
MessagePackSerializer.Typeless 是 Serialize/Deserialize<object>(TypelessContractlessStandardResolver.Instance)
的快捷方式。如果你想将其配置为默认解析器,可以使用 MessagePackSerializer.Typeless.RegisterDefaultResolver
。
TypelessFormatter 可以单独使用或与其他解析器组合使用。
/****************************************************文件:Test_07.cs作者:Edision日期:#CreateTime#功能:示例7:typeless
*****************************************************/using MessagePack;
using MessagePack.Formatters;
using UnityEngine;public class Test_07 : MonoBehaviour
{object mc = new MyClass(){Age = 10,FirstName = "hoge",LastName = "huga"};public void Test(){// Serialize with the typeless APIvar bin = MessagePackSerializer.Typeless.Serialize(mc);// 数据块中嵌入了类型-程序集信息。// ["MyClass, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",10,"hoge","huga"]Debug.Log(MessagePackSerializer.ConvertToJson(bin));// 你可以使用无类型的 API 再次反序列化为 MyClass// 请注意,在反序列化调用中不需要显式指定类型// 因为类型信息已嵌入到二进制数据块中var objModel = MessagePackSerializer.Typeless.Deserialize(bin) as MyClass;Debug.Log(objModel);//// Replaced `object` uses the typeless resolvervar resolver = MessagePack.Resolvers.CompositeResolver.Create(new[] { TypelessFormatter.Instance },new[] { MessagePack.Resolvers.StandardResolver.Instance });//如果类型名称后来被更改,你将无法再反序列化旧的数据块。//但是在这种情况下,你可以通过提供自己的 TypelessFormatter.BindToType 函数指定一个回退名称。MessagePack.Formatters.TypelessFormatter.BindToType = typeName =>{if (typeName.StartsWith("SomeNamespace")){typeName = typeName.Replace("SomeNamespace", "AnotherNamespace");}return Type.GetType(typeName, false);};}
}[MessagePackObject]
public class MyClass
{[Key(0)]public int Age { get; set; }[Key(1)]public string FirstName { get; set; }[Key(2)]public string LastName { get; set; }// 所有不应被序列化的字段或属性必须用 [IgnoreMember] 进行注解。[IgnoreMember]public string FullName { get { return FirstName + LastName; } }
}public class Foo
{// use Typeless(this field only)[MessagePackFormatter(typeof(TypelessFormatter))]public object Bar;
}
从不受信任的来源反序列化数据可能会给你的应用程序引入安全漏洞。根据反序列化过程中使用的设置,不受信任的数据可能能够执行任意代码或导致拒绝服务攻击。不受信任的数据可能来自网络上的不受信任源(例如任何和所有联网客户端),或者在通过未验证连接传输时被中间者篡改,也可能来自可能已被篡改的本地存储,或其他许多来源。MessagePack for C# 不提供任何验证数据或防止其被篡改的方法。请在反序列化之前使用适当的方法验证数据 - 例如 MAC(消息认证码)。
请注意这些攻击场景;过去,许多项目和公司以及序列化库用户都曾因不受信任的用户数据反序列化而遭受损失。
当反序列化不受信任的数据时,通过配置 MessagePackSerializerOptions.Security
属性将 MessagePack 设置为更安全的模式:
var options = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData);// Pass the options explicitly for the greatest control.
T object = MessagePackSerializer.Deserialize<T>(data, options);// Or set the security level as the default.
MessagePackSerializer.DefaultOptions = options;
MessagePack 是一种快速且紧凑的格式,但它不是压缩格式。LZ4 是一种极其快速的压缩算法,通过使用 LZ4,MessagePack for C# 可以实现极快的性能以及极其紧凑的二进制大小!
MessagePack for C# 内置了对 LZ4 的支持。你可以通过修改选项对象并将其传递给 API 来激活它,如下所示:
var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
MessagePackSerializer.Serialize(obj, lz4Options);
MessagePack.Unity 在应用程序启动时自动将 UnityResolver 添加到默认选项解析器中,使用 unity 包中的代码启用此序列化功能,如下所示:
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Init()
{MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard.WithResolver(UnityResolver.InstanceWithStandardResolver);
}
以下是一些在使用 MessagePack for C# 时实现最大性能的建议:
1. 使用索引键
-
使用索引键(
[Key(0)]
)而不是字符串键([Key("name")]
)可以显著提高序列化和反序列化的性能,因为索引键不需要处理和查找键名,且生成的二进制数据更紧凑。 -
示例:
[MessagePackObject] public class Person {[Key(0)]public string Name { get; set; }[Key(1)]public int Age { get; set; } }
2. 启用 LZ4 压缩
-
MessagePack for C# 内置了 LZ4 压缩支持,可以通过配置选项启用。LZ4 是一种快速的压缩算法,可以在不显著降低性能的情况下显著减小数据大小。
-
示例:
var options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); byte[] binary = MessagePackSerializer.Serialize(obj, options);
3. 优化数据结构
-
尽量使用简单的数据结构,避免嵌套过深的复杂结构,以减少序列化和反序列化的时间。
-
如果需要处理大量数据,可以考虑批量处理,减少单次操作的开销。
4. 使用 IBufferWriter<byte>
或 Stream
API
-
默认情况下,
MessagePackSerializer.Serialize
返回byte[]
,这会涉及额外的内存拷贝。使用IBufferWriter<byte>
或Stream
API 可以直接写入缓冲区,避免不必要的内存分配。 -
示例:
using var stream = new MemoryStream(); MessagePackSerializer.Serialize(stream, obj, options);
5. 避免使用无合同解析器
-
无合同解析器(Contractless)虽然方便,但会牺牲性能。如果性能是首要目标,建议显式使用
[MessagePackObject]
和[Key]
特性。
6. 注意版本控制
-
当类结构发生变化时,使用索引键时应保留废弃成员的索引,直到所有客户端都更新。
7. 调整压缩模式
-
如果数据中存在大量重复内容,启用压缩可以显著减小数据大小。但需要注意,压缩效果因数据而异,建议根据实际数据测试压缩的实际效果。
通过以上优化,可以在使用 MessagePack for C# 时实现更高的性能和更紧凑的数据传输。
相关文章:
DeepSeek教unity------MessagePack-06
无类型 Typeless 无类型的 API 类似于 BinaryFormatter,因为它会将类型信息嵌入到数据块中,所以在调用 API 时不需要显式指定类型。 MessagePackSerializer.Typeless 是 Serialize/Deserialize<object>(TypelessContractlessStandardResolver.In…...

2.【BUUCTF】bestphp‘s revenge
进入题目页面如下 进行代码审计 <?php // 1. 高亮显示当前PHP文件的源代码,方便开发者查看代码内容,在生产环境中不应使用此函数,可能会导致代码泄露。 highlight_file(__FILE__);// 2. 定义变量 $b ,其值为字符串 implode &…...

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
拉票 亲爱的小伙伴们或者童鞋们,喜欢宏哥文章的,请动动你们发财小手,给我投投票票 。 祝2025小伙伴们工作顺利,家庭和睦,心想事成,财源滚滚! 我的票还有7票,互票的朋友私信给我。 投…...
Netty源码解析之异步处理(二):盛赞Promise中的集合设计
前言 在阅读Netty源码的过程中,我越来越相信一句话:“Netty的源码非常好,质量极高,是Java中质量最高的开源项目之一”。如果认真研究,会有一种遍地黄金的感觉。 本篇文件我将记录一下鄙人在Promise的实现类DefaultPr…...

NetworkX布局算法:nx.spring_layout
诸神缄默不语-个人CSDN博文目录 官方文档:https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html 和nx.fruchterman_reingold_layout()等价。 这个函数主要是为了在可视化NetworkX图时设置节点分布布局的&…...

Navicat导入海量Excel数据到数据库(简易介绍)
目录 前言正文 前言 此处主要作为科普帖进行记录 原先Java处理海量数据的导入时,由于接口超时,数据处理不过来,后续转为Navicat Navicat 是一款功能强大的数据库管理工具,支持多种数据库系统(如 MySQL、PostgreSQL、…...
LeetCodehot100 力扣热题100 二叉树展开为链表
代码思路 目标: 将二叉树展平(flatten)为一个单链表。展平后的链表应该按照前序遍历的顺序排列节点,即: • 节点的左子树指针设置为 nullptr。 • 节点的右子树指针指向下一个节点。 代码注释及思路 class Solution…...

2.14学习总结
#include <stdio.h> #include <stdlib.h> #include <math.h>#define MAX_N 32767// 二分查找最接近目标值的元素 int binarySearch(int* arr, int left, int right, int target) {while (left < right) {int mid left (right - left) / 2;if (arr[mid] …...

在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程
既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…...
zola + github page,用 workflows 部署
之前的Zola都是本地build之后,再push到github上,这种方式很明显的弊端就是只能在本地编辑,而不能通过github编辑,再pull到本地,缺乏了灵活性。因此将zola用workflows来部署。 repo地址:https://github.com/…...
【科技革命】颠覆性力量与社会伦理的再平衡
目录 2025年科技革命:颠覆性力量与社会伦理的再平衡目录技术突破全景图认知智能的范式转移量子霸权实现路径生物编程技术革命能源结构重构工程 产业生态链重构医疗健康新范式教育系统智能进化金融基础设施变革制造范式革命 科技伦理与文明演进 2025年科技革命&#…...

UIView 与 CALayer 的联系和区别
今天说一下UIView 与 CALayer 一、UIView 和 CALayer 的关系 在 iOS 开发中,UIView 是用户界面的基础,它负责处理用户交互和绘制内容,而 CALayer 是 UIView 内部用于显示内容的核心图层(Layer)。每个 UIView 内部都有…...

Jenkins 新建配置 Freestyle project 任务 六
Jenkins 新建配置 Freestyle project 任务 六 一、新建任务 在 Jenkins 界面 点击 New Item 点击 Apply 点击 Save 回到任务主界面 二、General 点击左侧 Configure Description:任务描述 勾选 Discard old builds Discard old builds:控制何时…...
深入解析A2DP v1.4协议:蓝牙高质量音频传输的技术与实现
1. A2DP概述 A2DP(Advanced Audio Distribution Profile)是一种高质量音频流媒体协议,旨在实现高质量音频内容的分发,通常用于通过蓝牙设备传输音频数据,例如将音乐从便携式播放器传输到耳机或扬声器。与传统的蓝牙语…...

mybatis-plus逆向code generator pgsql实践
mybatis-plus逆向code generator pgsql实践 环境准备重要工具的版本供参考pom依赖待逆向的SQL 配置文件CodeGenerator配置类配置类说明 环境准备 重要工具的版本 jdk1.8.0_131springboot 2.7.6mybatis-plus 3.5.7pgsql 14.15 供参考pom依赖 <?xml version"1.0&quo…...
Android Studio:RxBus结合ICompositeSubscription使用
我现在想用 RxBus 来发布和订阅事件,同时使用 ICompositeSubscription 来管理订阅。跟前一个博客的区别在于,事件流的产生方式不同,更加得全面。 目标 使用 RxBus 发布事件。使用 ICompositeSubscription 来管理订阅。在 Activity 中创建订…...

微软AutoGen高级功能——Magentic-One
介绍 大家好,博主又来给大家分享知识了,这次给大家分享的内容是微软AutoGen框架的高级功能Magentic-One。那么它是用来做什么的或它又是什么功能呢,我们直接进入正题。 Magentic-One Magnetic-One是一个通用型多智能体系统,用于…...

redis cluster测试
集群节点信息这时候停掉一个master 172.30.60.31 从集群信息集中我们可以看到172.30.60.31的slave是172.30.60.41,查看41的日志,发现他成为了新的master 这时候我们在将172.30.60.41也杀死,会发现集群异常了 尝试把172.30.60.31启动ÿ…...

【ARM】JTAG接口介绍
1、 文档目标 对 JTAG 接口有更多的认识,在遇到关于 JTAG 接口问题时有一些排查的思路。 2、 问题场景 在使用调试器过程时,免不了要接触到 JTAG 接口,当出现连接不上时,就不知道从哪来进行排查。 3、软硬件环境 1 软件版本&am…...

处理项目中存在多个版本的jsqlparser依赖
异常提示 Correct the classpath of your application so that it contains a single, compatible version of net.sf.jsqlparser.statement.select.SelectExpressionIte实际问题 原因:项目中同时使用了 mybatis-plus 和 pagehelper,两者都用到了 jsqlpa…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...