10

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?

stackers
  • 2,701
  • 4
  • 34
  • 66

4 Answers4

28

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.

CherryDT
  • 25,571
  • 5
  • 49
  • 74
  • Thank you, that makes sense (and does seem to work now). – stackers Oct 07 '21 at 19:31
  • Also I wonder if the %s part in the documentation examples is automatically forcing it to be converted to a string, which is why toString is not needed (and I suspect that JSON.stringify does that too, which I've seen a few times exclude toString) – stackers Oct 07 '21 at 19:49
  • Even then the example would be misleading, as is apparent from this very question. – CherryDT Oct 07 '21 at 20:08
  • Do you know of an official documentation for this outside of the github repository? I can't find anything on this or the react version of websockets. – Martin Watson Oct 31 '22 at 17:31
  • 1
    What do you mean? The _official_ GitHub repo has the _official_ documentation (https://github.com/websockets/ws), why would it need another one? – CherryDT Oct 31 '22 at 17:53
  • @stackers Thanks for the edit suggestion but this is a citation from the changelog and therefore it doesn't make sense to change it. Also, the logic does seem correct - if it's binary, it cannot be properly converted to a string, so it should stay as buffer; otherwise it is converted to string. – CherryDT Apr 26 '23 at 11:23
1

If you use console.log(` ${data} `), it will not show <Buffer. where as if you console.log(data), it will show <Buffer e.g.

    ws.on('message',data=>{
        console.log(`user sended:${data}`)
    })

It's a bug or normal you can say.

alter method:

    ws.on('message',data=>{
        data=data.toString()
        console.log("user sended:",data)
    })

OR

    ws.on('message',data=>{
        console.log("user sended:",data.toString())
    })
aakash4dev
  • 774
  • 4
  • 13
  • It's not a bug, it's simply because in one case you coerce it to a string by using it in a template literal and in the other case you don't. – CherryDT Apr 28 '23 at 07:39
0

In Latest version one need to provide %s while printing the received message. Here is the simple code snippet from official page npm websocket official page.

ws.on('message', function message(data) {
  console.log('received: %s', data);
});
Vikash Singh
  • 884
  • 8
  • 11
0

I was having same issue. I found the issue was because of version of ws.
So, I installed another version of ws.

Try this instead:

npm i ws@7.5.0 

It worked in my case.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31