WebSocket传输Protobuf格式数据实例 JS解析二进制流数据方法

陌枫大大_4881

陌枫大大_4881

2026-05-25

711人浏览

原创

websocket收到event.data是blob还是arraybuffer取决于服务端发送内容及前端是否设置socket.binarytype;浏览器默认为blob,但protobuf解码需uint8array或arraybuffer,故连接建立后应立即设socket.binarytype = 'arraybuffer'。

websocket传输protobuf格式数据实例 js解析二进制流数据方法

WebSocket收到event.data是Blob还是ArrayBuffer?

取决于服务端发的是什么,也取决于你有没有提前设socket.binaryType。浏览器默认把二进制帧当作Blob对象传给onmessage,但Blob不能直接喂给Protobuf解码器——它得先转成Uint8Array或ArrayBuffer。

所以连接一建立就得立刻执行:

socket.binaryType = 'arraybuffer';

这样后续所有event.data就是ArrayBuffer,省去Blob.arrayBuffer()这一步。如果漏了这行,你会在控制台看到TypeError: Cannot read property 'length' of undefined之类报错,因为Message.decode()不认Blob。

  • 服务端发的是BinaryWebSocketFrame(如Netty)或bytes字段(如FastAPI),且前端没设binaryType → event.data是Blob
  • 设了socket.binaryType = 'arraybuffer' → event.data是ArrayBuffer,可直接用new Uint8Array(event.data)
  • 用protobuf-ts时,decode()只接受Uint8Array;用protobufjs老版本,部分API接受ArrayBuffer但更推荐统一转Uint8Array

Message.decode()报错“invalid wire type”或“truncated”怎么处理?

这两个错误基本都指向一个事实:你传进去的字节数组长度不对,或者开头几个字节被截断/污染了。

Protobuf wire format对数据完整性极其敏感,哪怕少1个字节、多1个BOM头,都会解码失败。移动端弱网下尤其常见。

Wjs Uploading Video
Wjs Uploading Video

将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。

下载
  • 先校验长度:if (event.data.byteLength —— 最小合法Protobuf包至少含1字节tag+1字节value(比如单个<code>sint32字段)
  • 确认服务端没加额外包头(如自定义4字节长度前缀);如果加了,必须手动切掉:const payload = new Uint8Array(event.data, 4)
  • 检查是否误把字符串当二进制发:后端用JSON.stringify()再atob()转Base64,前端又用Uint8Array.from(atob(...), c => c.charCodeAt(0))——这种链式编码极易出错,应直接走原生二进制
  • 开发期开启protobuf-ts的strict模式,它会在字段缺失或类型错位时抛明确错误,而不是静默失败

用protobuf-ts还是protobufjs?选型关键差异

不是功能差多少,而是体积、TS支持和默认行为是否贴合现代前端工程。

protobuf-ts编译产物约15KB(gzip后),零运行时反射,生成代码带完整TS类型;protobufjs全量包超70KB,需手动loadProtoFile或预编译,且默认启用动态解析,容易在tree-shaking时残留无用代码。

  • Vue3/Vite/SvelteKit项目优先选protobuf-ts:npx protoc --ts_out=. --plugin=protoc-gen-ts ./msg.proto,然后import { PlayerPosition } from "./proto/msg.js"
  • 若必须用protobufjs(比如要兼容IE11),务必用pbjs -t static-module生成JS模块,别用load()动态加载,否则.proto文件会暴露在源码中
  • 两者对packed=true、sint32等优化特性的支持一致,但protobuf-ts默认禁用int64(强制转string),避免JS精度丢失,这点很关键

高频小包场景下,为什么repeated int32 x = 1 [packed=true]比普通repeated省一半流量?

Protobuf wire type 2(length-delimited)用于普通repeated,每个元素都带独立tag+length+value;而packed=true改用wire type 2 + 单次length前缀,把多个数值连续写入,省掉重复tag和length开销。

比如发送[1, 2, 3, 4, 5]五个int32:

  • 未packed:每个数占5字节(1字节tag + 4字节值)→ 共25字节
  • 启用packed:1字节tag + 1字节length(表示20字节内容) + 20字节纯数值 → 共22字节,且随数量增长优势放大
  • 移动端每秒10次位置同步,一年下来能省几百MB流量,这不是理论值,是实测值

真正容易被忽略的是:这个优化必须前后端协议定义完全一致——只要有一端没加[packed=true],解码就会失败或丢数据。上线前务必用真实二进制dump比对两端输出。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

js websocket

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

4356

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

1335

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1738

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

9903

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

960

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2684

5

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1549

5

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

2023.09.21

4609

3

js生成随机数方法
js生成随机数方法

JavaScript生成随机数的方法,包括使用Math.random()方法生成指定范围内的随机整数、生成随机字符串和生成随机颜色。根据具体需求,可以选择适合的方法来生成随机数,以实现各种功能 。

2023.09.25

2655

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习