websockets / ws

Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
MIT License
21.34k stars 2.3k forks source link

Invalid UTF-8 sequence even though the message is encoded #2227

Closed DAV3Y06L3GO closed 1 month ago

DAV3Y06L3GO commented 1 month ago

Is there an existing issue for this?

Description

const msg = JSON.stringify({ type: "request_phone", data: true });
console.log(isValidUTF8(Buffer.from(msg)));
clients.get(esp).send(msg);

This code throws a "invalid UTF-8 sequence error" even though it is encoded in UTF8. I've looked through the code a bit and I don't understand why this error is thrown when JSON.stringify returns a utf-8 encoded string.

ws version

8.16.0

Node.js Version

20.11.1

System

System: OS: Windows 11 10.0.22631 CPU: (8) x64 Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz Memory: 7.31 GB / 15.88 GB

Expected result

The message should've been successfully sent

Actual result

Recieved: "Error: Invalid WebSocket frame: invalid UTF-8 sequence

Attachments

No response

lpinca commented 1 month ago

Please write a minimal reproducible test case. I can't reproduce the issue.

import { WebSocket, WebSocketServer } from 'ws';

const server = new WebSocketServer({ port: 0 }, function () {
  const ws = new WebSocket(`ws://127.0.0.1:${server.address().port}`);

  ws.on('open', function () {
    const msg = JSON.stringify({ type: 'request_phone', data: true });

    ws.send(msg);
  });
});

server.on('connection', function (ws) {
  ws.on('message', function (buf) {
    console.log(buf.toString());
  });
});
DAV3Y06L3GO commented 1 month ago
const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 80 }, () => console.log("WS listening on port 80"));

wss.on('connection', (ws) => {
    const msg = JSON.stringify({ type: 'request_phone', data: true });

    ws.send(msg);
});

const socket = new WebSocket("ws://127.0.0.1:80");

socket.on('message', (message) => {
    console.log("RECIEVED:", message);
});

This test reproduces the error on my end

lpinca commented 1 month ago

I still can't reproduce the issue.

import { WebSocket, WebSocketServer } from 'ws';

const server = new WebSocketServer({ port: 0 }, function () {
  const ws = new WebSocket(`ws://127.0.0.1:${server.address().port}`);

  ws.on('open', function () {
    ws._socket.prependListener('data', function (chunk) {
      console.log(chunk);
    });
  });

  ws.on('message', function (buf) {
    console.log(buf.toString());
  });
});

server.on('connection', function (ws) {
  const msg = JSON.stringify({ type: 'request_phone', data: true });

  ws.send(msg);
});

Check the bytes that are received on the destination copying the example above or with something like WireShark. Maybe a third party software is changing the data.

DAV3Y06L3GO commented 1 month ago

I think the issue has something to do with my ESP32. when I ran the test yesterday my ESP accidentally connected to the test server but now when I unplug the ESP it doesn't throw the error.