socketio / socketio/socket.io

A client receiving an `Object` with more than 10 binary fields closes the connection

Open
#5,504 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
TypeScript
Stars
63.2k
Forks
10.3k
Avg merge
11d 20h
Merged PRs (30d)
2

Description

Describe the bug

When the Python or Node.js server sends an Object containing more than 10 binary fields to a web browser JS client got via NPM, it fails and the connection is interrupted.

The issue doesn't happen when the package is got via the CDN.

To Reproduce

Socket.IO server version: 4.8.3

Server

import { createServer } from 'http';
import { Server } from 'socket.io';

const PAYLOAD = Buffer.alloc(1); // Size doesn't matter

const httpServer = createServer();
const io = new Server(httpServer, {
    cors: { origin: "*" },
});

io.on('connection', (socket) => {
    console.log(`[socket ${socket.id}] connected`);

    socket.on('request_data', () => {
        socket.emit('data', {
            "1": PAYLOAD,
            "2": PAYLOAD,
            "3": PAYLOAD,
            "4": PAYLOAD,
            "5": PAYLOAD,
            "6": PAYLOAD,
            "7": PAYLOAD,
            "8": PAYLOAD,
            "9": PAYLOAD,
            "10": PAYLOAD,
            "11": PAYLOAD, // Commenting this line makes the issue disappear
        });
    });

    socket.on('disconnect', reason => {
        console.log(`[socket ${socket.id}] disconnected: ${reason}`);
    });
});

httpServer.listen(8000, 'localhost', () => {
    console.log('Server running at http://localhost:8000');
});

In Python with python-socketio 5.16.2 and uvicorn[standard] 0.48.0:

import socketio
import uvicorn

sio = socketio.AsyncServer(
    async_mode='asgi',
    cors_allowed_origins="*",
)

PAYLOAD = b"\x00" * 1  # Size doesn't matter

@sio.event
async def request_data(sid: str) -> None:
    await sio.emit('data', {
        "1": PAYLOAD,
        "2": PAYLOAD,
        "3": PAYLOAD,
        "4": PAYLOAD,
        "5": PAYLOAD,
        "6": PAYLOAD,
        "7": PAYLOAD,
        "8": PAYLOAD,
        "9": PAYLOAD,
        "10": PAYLOAD,
        "11": PAYLOAD,  # Commenting this line makes the issue disappear
    })

app = socketio.ASGIApp(sio)

if __name__ == '__main__':
    uvicorn.run(
        app,
        host='localhost',
        port=8000,
    )

Socket.IO client version: 4.8.3

Client

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

const socket = io(`http://localhost:8000`);

socket.on('data', data => {
    console.log("Received data");
    console.log(data);
});

document.querySelector('#app').innerHTML = `
    <button id="requestData" type="button">Request Data</button>
`;

document.querySelector('#requestData').addEventListener(
    'click', () => socket.emit('request_data')
);
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vite-project</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

Expected behavior

The message should be transmitted, showing in the browser console (F12), and the transport not disconnected.

Platform:

  • Device: x64 computer
  • OS: Linux Mint 22.3

Additional context

The issue does not happen via CDN:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Socket.IO</title>
</head>
<body>
    <button id="requestData" type="button">Request Data</button>
    <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
    <script>
        const socket = io('http://localhost:8000');

        document.getElementById('requestData').addEventListener('click', () => {
            socket.emit('request_data');
        });

        socket.on('data', data => {
            console.log("Received data");
            console.log(data);
        });
    </script>
</body>
</html>

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the provided Python or Node.js server and the NPM socket.io-client, then compare it with the CDN bundle. Start at the client package entry point and trace handling of the data event with 11 binary fields. Done when the message reaches the browser and the transport stays connected.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs, python, typescript
Domain
full-stack, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.