为啥接收到的 websocket 数据作为缓冲区出来?

Posted

技术标签:

【中文标题】为啥接收到的 websocket 数据作为缓冲区出来?【英文标题】:Why is received websocket data coming out as a buffer?为什么接收到的 websocket 数据作为缓冲区出来? 【发布时间】:2021-10-07 17:24:40 【问题描述】:

我正在尝试做一个非常基本的 websocket,但我不明白为什么我没有得到一个字符串。

我正在使用来自 npm 的 ws 模块作为服务器。 https://github.com/websockets/ws

客户:

    let socket = new WebSocket('wss://upload.lospec.com');

    socket.addEventListener('open', function (event) 
        socket.send('test');
    );

服务器:

const wss = new WebSocket.Server( server );

wss.on("connection", function (ws) 
    ws.on("message", function (asdfasdf) 
        console.log("got new id from client",asdfasdf);
    );

服务器结果:

got new id from client <Buffer 74 65 73 74>

尝试遵循文档中的示例以及本教程:https://ably.com/blog/web-app-websockets-nodejs

但它不像两个地方都承诺的那样输出。

为什么这不是一个字符串?

【问题讨论】:

【参考方案1】:

您可能使用与教程不同的ws 版本。看来本教程使用的是比 v8 更早的版本,而您使用的是 v8+ 版本。

来自changelog for 8.0.0:

文本消息和关闭原因不再被解码为字符串。它们作为Buffers 传递给各自事件的侦听器。 'message' 事件的侦听器现在采用布尔参数指定消息是否为二进制 (e173423)。

可以通过显式解码缓冲区来迁移现有代码。

websocket.on('message', function message(data, isBinary) 
  const message = isBinary ? data : data.toString();
  // Continue as before.
);
websocket.on('close', function close(code, data) 
  const reason = data.toString();
  // Continue as before.
);

这也描述了解决方案。

或者,您可以降级到 ws 的 7.5.0 版,以与 what the tutorial uses 保持一致:

npm i ws@7.5.0

关于库文档中的“发送和接收文本数据”示例:我认为在 v8 发布时未更新此示例是他们的疏忽。你可以在 GitHub 上打开一个问题让他们知道。

【讨论】:

谢谢,这是有道理的(现在看来确实有效)。 另外我想知道文档示例中的 %s 部分是否会自动强制将其转换为字符串,这就是不需要 toString 的原因(我怀疑 JSON.stringify 也会这样做,我见过几次排除toString) 即使这样,这个例子也会产生误导,正如从这个问题中显而易见的那样。

以上是关于为啥接收到的 websocket 数据作为缓冲区出来?的主要内容,如果未能解决你的问题,请参考以下文章

python的websocket在哪里存储它接收到的数据

如何得知socket的缓存大小,这个缓存是不是有

通过 websocket 接收文件并启动下载对话框

如何将 JSON 数据与从 websocket 接收的 ArrayBuffer 分离

清除 javascript Websocket 上的缓冲区

Windows 串行:在接收到起始字节之前丢弃输入缓冲区中接收到的所有字节