Why is received websocket data coming out as a buffer?

I’m trying to do a very basic websocket, but i dont understand why I’m not getting a string back.

I’m using the ws module from npm for the server. https://github.com/websockets/ws

client:

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

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

server:

const wss = new WebSocket.Server({ server });

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

server result:

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

Trying to follow the examples on the docs, as well as this tutorial: https://ably.com/blog/web-app-websockets-nodejs

But it’s not coming out like a string like both places promise.

Why isn’t this coming out as a string?

Answer

You probably use a different version of ws than the tutorial does. It seems like the tutorial uses a version older than v8, while you use a version of v8+.

From the changelog for 8.0.0:

Text messages and close reasons are no longer decoded to strings. They are passed as Buffers to the listeners of their respective events. The listeners of the 'message' event now take a boolean argument specifying whether or not the message is binary (e173423).

Existing code can be migrated by decoding the buffer explicitly.

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.
});

This also describes the solution.

Alternatively, you can downgrade to version 7.5.0 of ws to be on par with what the tutorial uses:

npm i ws@7.5.0

In regards to the example “sending and receiving text data” in the library docs: I believe it’s an oversight on their end that this example wasn’t updated when v8 was released. You could open an issue on GitHub to let them know.