v3 and v4 close socket if more than 1MB is sent (but v2 is fine)
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
1e6in 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 insocket.io@2, which works just fine. - I debugged the issue and found that
N=1e6will disconnect, whileN=999000will 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
onClosehandler in./node_modules/engine.io-client/lib/transports/websocket.js, you can debug the native WebSocket error event (which is inarguments[0]).- It's code is
1005. - According to MDN, code 1005 - "Indicates that no status code was provided even though one was expected."
- It's code is
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
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?
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
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!