socket.io icon indicating copy to clipboard operation
socket.io copied to clipboard

v3 and v4 close socket if more than 1MB is sent (but v2 is fine)

Open Domiii opened this issue 4 years ago • 3 comments

Describe the bug

  • Everytime a certain amunt of data is sent by the client, the socket disconnects instantly.
  • I am using [email protected]
  • Client in browser (latest Chrome)
  • Server on Node@16

Steps to reproduce

  • Connect to server
  • Let client send a packet that is at least 1e6 in size (code sample below)
  • You will see it disconnect instantly.

Code Sample

Socket.IO server version: 4.1.2

Server

import { Server } from "socket.io";

const io = new Server(3000, {});

io.on("connection", (socket) => {
  console.log(`connect ${socket.id}`);

  socket.on("disconnect", () => {
    console.log(`disconnected ${socket.id}`);
  });

  socket.on("noop", (data) => {
    console.log(`noop received: ${data.length}`);
  });
});

Socket.IO client version: 4.1.2

Client

import { io } from "socket.io-client";

const socket = io("ws://localhost:3000/", {});

socket.on("connect", () => {
  console.log(`connect ${socket.id}`);

  // NOTE: if you change N to 999000, it will NOT disconnect!
  const N = 1e6;
  const noopData = new Array(N).fill(1).join('');
  socket.emit('noop', noopData);
  console.warn(`noop sent, N=${N}`);
});

socket.on("disconnect", () => {
  console.log("disconnect");
});

Expected behavior

Don't disconnect arbitrarily.

Platform:

  • Device: PC
  • OS: Windows10

Further Analysis

  • I find the issue to also exist in socket.io@3, but not in socket.io@2, which works just fine.
  • I debugged the issue and found that N=1e6 will disconnect, while N=999000 will NOT disconnect.
    • That seems to indicate that whatever bug it is, it is largely tied to some sort of 1MB quota.
  • When putting a breakpoint in the onClose handler in ./node_modules/engine.io-client/lib/transports/websocket.js, you can debug the native WebSocket error event (which is in arguments[0]).
    • It's code is 1005.
    • According to MDN, code 1005 - "Indicates that no status code was provided even though one was expected."

Domiii avatar May 28 '21 10:05 Domiii

Yes, this is expected, the maxHttpBufferSize value has been decreased from 100 MB to 1MB in v3, you can update it with:

const io = require("socket.io")(httpServer, {
  maxHttpBufferSize: 1e8
});

Reference:

  • https://socket.io/docs/v4/server-initialization/#maxHttpBufferSize
  • https://socket.io/docs/v4/migrating-from-2-x-to-3-0/#Saner-default-values
  • https://socket.io/docs/v4/troubleshooting-connection-issues/#You-are-trying-to-send-a-huge-payload

darrachequesne avatar May 28 '21 22:05 darrachequesne

Thanks for the quick reply! Would be fantastic if one received a corresponding error message or warning, rather than just a silent shutdown. At least in development mode, it could have some sanity checks, to my mind. Considering that the close event has an error code, at least that can be reported on.

Can you possibly consider converting this from bug report to feature request?

Domiii avatar May 29 '21 19:05 Domiii

Can you possibly consider converting this from bug report to feature request?

Yes, we could indeed make the error more user-friendly :+1:

Possibly linked: https://github.com/socketio/socket.io/issues/3237

darrachequesne avatar Jun 03 '21 12:06 darrachequesne

Closed by https://github.com/socketio/engine.io-client/commit/b9252e207413a850db7e4f0f0ef7dd2ef0ed26da, included in [email protected].

socket.on("close", (reason, details) => {
  console.log(reason); // "transport error"

  // in that case, details is an error object
  console.log(details.message); "xhr post error"
  console.log(details.description); // 413 (the HTTP status of the response)

  // details.context refers to the XMLHttpRequest object
  console.log(details.context.status); // 413
  console.log(details.context.responseText); // ""
});

Please reopen if needed!

darrachequesne avatar Oct 14 '22 07:10 darrachequesne