WebSocket序列化Float32Array转ArrayBuffer遇Array.from空数组问题
让我来帮你拆解两个核心问题,以及给出正确的处理流程:
1. 为什么Array.from(parsed)返回空数组?
这几乎可以肯定是因为你序列化Float32Array的方式不正确。
当你直接对Float32Array执行JSON.stringify()时,它不会被序列化为我们预期的普通数组,而是会变成一个包含索引键和length属性的对象(举个例子:{"0": 1.5, "1": 2.7, "length": 2})。虽然这个对象看起来像类数组,但Array.from()对这类对象的处理有严格要求:它需要对象的length是有效的非负整数,且从0到length-1的索引属性都存在。如果你的parsed对象不符合这个条件(比如length为0,或者索引不连续),Array.from()就会返回空数组。
正确的序列化方式是先把Float32Array转成普通数组再序列化(发送端代码):
const floatData = new Float32Array([1.0, 2.5, 3.7]); const serializedData = JSON.stringify(Array.from(floatData)); // 再通过WebSocket发送serializedData
这样接收端JSON.parse(streamData)得到的就是标准的普通数组,此时甚至不需要Array.from(parsed)——直接用parsed就能创建Float32Array。
2. 你创建ArrayBuffer的方式完全错误
new ArrayBuffer(arr32)这一行有问题:ArrayBuffer的构造函数接受的是字节长度(数字),而不是Float32Array实例。
实际上,Float32Array本身就和一个ArrayBuffer绑定在一起,你可以直接通过它的buffer属性获取对应的缓冲区。
完整的正确接收流程
// 接收端代码 const parsed = JSON.parse(streamData); // 现在是普通数组 const arr32 = new Float32Array(parsed); // 用普通数组创建Float32Array const kbuff = arr32.buffer; // 获取关联的ArrayBuffer
如果必须从非数组的序列化对象恢复
假设你没办法修改发送端的序列化逻辑,只能处理解析后的对象(比如{0: 1.0, 1:2.5, length:2}),可以这样处理:
const parsed = JSON.parse(streamData); const arr32 = new Float32Array(parsed.length); // 手动填充数据 for (let i = 0; i < parsed.length; i++) { arr32[i] = parsed[i]; } const kbuff = arr32.buffer;
内容的提问来源于stack exchange,提问作者Koby Douek

