WebSocketPeer.send_text() not sending string to server

Godot Version

v4.1.2.stable.official [399c9dc39]

Question

WebSocketPeer.send_text() not sending text?

I have been trying to implement WebRTC multiplayer in my project by following the WebRTC signaling demo. I have a google cloud vm running the server.js script provided, and have been able to connect to the server fine, but when the demo ws_webrtc_client.gd file sends a message:

ws.send_text(JSON.stringify({
“type”: type,
“id”: id,
“data”: data
}))

It should be sending a string, right? but my server output is a hex code:

<Buffer 7b 22 64 61 74 61 22 3a 22 62 22 2c 22 69 64 22 3a 30 2c 22 74 79 70 65 22 3a 30 7d>

Which when decoded becomes the string that I want to send anyway. When I try using send() instead:

ws.send(JSON.stringify({
“type”: type,
“id”: id,
“data”: data
}).to_utf8_buffer())

My server outputs the exact same:

<Buffer 7b 22 64 61 74 61 22 3a 22 62 22 2c 22 69 64 22 3a 30 2c 22 74 79 70 65 22 3a 30 7d>

Here’s the block of code in the server.js file that is catching the error:

ws.on(‘message’, (message) => {
console.log(message);
if (typeof message !== ‘string’) {
ws.close(4000, STR_INVALID_TRANSFER_MODE);
return;
}

WebSocketPeer.send() takes in a PackedByteArray, so I’m assuming that’s what the server output is showing, but I could be wrong. My main assumption is that something is happening to the string somewhere behind the scenes to convert it to this, but I’ve looked through the implementation on github and can’t seem to find anything. I’m new to js though so it could just be that I’m missing something in the demo project. I don’t really know what ws.on() does either.

Let me know if more info is needed.

Solved! Per u/lmystique on reddit:
Most likely, you have the wrong version of ws Node.js package installed on the server. The demo uses 7.5.9. The latest version at this moment is 8.16.0, and the changelog indicates that, indeed, v8 changed message type from string to Buffer.

Did you install the package manually instead of doing plain npm install? I.e. did you run npm install ws? Then you have specify the version manually as well, like so: npm install ws@'^7.5.9'.

Now, if you do want to stick to the newer version of ws and tinker with the server code instead… Well, WebSocket does not have a concept of “type”, messages are always sent as byte streams. However you send the message from the client only affects how you prepare the data on the client ― the server will never know whether you sent a string or a buffer. That’s what is happening. At this point, you can probably just replace the check with message instanceof Buffer, and then use message.toString() to get an actual string out of it.