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>或StreamAPI 可以直接写入缓冲区,避免不必要的内存分配。 -
示例:
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…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
