我正在填充ArrayBuffer
,其中包含要通过WebSocket
发送的数据。
数据的大小可变,因此在序列化时,我会根据需要动态扩展ArrayBuffer
。
然而,当序列化过程完成时,我经常在缓冲区的末尾有一些我不想发送的空间。
可以将所需的部分复制到新的ArrayBuffer
,但这在内存和CPU方面是浪费的。
是否可以在ArrayBuffer
上发送WebSocket
的子部分而无需复制?如果没有,是否还有另一种方法可以避免复制的性能损失?
进行一些澄清。
核心问题是WebSocket.send
只接受DOMString
,ArrayBuffer
或Blob
。这些似乎都需要一个完整的缓冲区,而不是缓冲区的视图。
我不知道当我开始序列化时缓冲区有多大,因此它从64字节开始并在每次溢出时加倍。那已经是一些复制,但我可以调整初始大小,以便溢出是例外。我想避免的是必须将序列化数据从超大缓冲区中复制出来。
在psuedo-JS中:
function serialiseAndSend(webSocket, message) {
// Allocate a buffer (assume it's large enough)
const buffer = new ArrayBuffer(64);
// Serialise into that buffer, and obtain the number of bytes written (<= 64)
const bytesWritten = serialise(buffer, message);
// The first 'bytesWritten' bytes of 'buffer' contain my message, the rest is zeroed.
//
// I want to send that sub-portion without allocating another buffer.
// This function would be great (buffer, start, count) but doesn't exist
webSocket.send(buffer, 0, bytesWritten);
// Instead I think I have to allocate and send a copy
const copy = buffer.slice(0, bytesWritten);
webSocket.send(copy);
}
这种模式在其他平台/语言中很常见,似乎是WebSocket API的疏忽。但是我知道它是由经验丰富的开发人员设计的,我希望有一种方法可以做我之前没有遇到过的事情。
答案 0 :(得分:2)
修改,更新
MDN不是specification。关于.send()
WebSocket
方法的MDN文档省略了实际规范中包含的ArrayBufferView
选项,请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1409752。
您可以使用.subarray()
为现有TypedArray
另请注意,这是在现有缓冲区上创建新视图; 对新对象内容的更改将影响原始对象 反之亦然。