socketio / socketio/socket.io

Server-Side Event "connection" not fired/called on Client-Connection (using wild-card namespaces)

Open
#4,677 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Describe the bug
We use socket.io with Google Cloud Run with with redis-adapter for exchanging data across node-cluster and multiple containers. The challenge is that Google Cloud Run kills the connections every 60min, we don't use sticky extension as we work on websockets only ourselves. Thus do not support polling. When scaling the containers no matter in which direction, it happens from time to time that the client gets a socket connection, but from server the event "connection" is not called. As a result, all other events on the socket itself do not work.

Important: We use Namespaces and Channels

To Reproduce

  1. create a system with multiple servers and node-cluster
  2. use redis-adapter for exchange between all nodes
  3. just connect with the clients, simulate disconnects, or wait for normal disconnect from server (tcp)
  4. sometimes it works sometimes not, connection will not fired

Version for frontend and backend:
"@socket.io/admin-ui": "^0.5.1",
"@socket.io/redis-adapter": "^8.1.0",
"redis": "^4.6.5",
"socket.io": "^4.6.1",
"socket.io-client": "^4.6.1",

Redis Server 6.x+ (issue also with redis server 4.x+)

Server
Code Example

import { Server } from "socket.io";
/* ... */
// initialize socket io
const io = new Server(app.http, {
    noServer: true,
    cors: {
        origin: "*",
        methods: ["GET", "POST"],
        credentials: true
    }
});
const redisPub = activeRedisClient.duplicate();
await redisPub.connect();
await redisPub.ping();
const redisSub = activeRedisClient.duplicate();
await redisSub.connect();
await redisSub.ping();
io.adapter(createAdapter(redisPub, redisSub, {
    requestsTimeout: 3000
}));

const dynamicNamespace = io.of(async (name, auth, next) => {
    next(null, true);
});
dynamicNamespace.use(async (socket, next) => { next(null); });

dynamicNamespace.on('connection', async (socket) => {
   // this event sometimes not called
    socket.on('disconnect', async () => {
        // this event sometimes not added / called
    });

    socket.on('message', async () => {
        // this event sometimes not added / called
    });
});

Client

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

const socket = io("ws://localhost:3000/", {
    transports: ['websocket'],
    auth: {
        token: 'jwt-token',
    },
});

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

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

Expected behavior
It is expected that the event "connection" is always called on the server. But this is not the case, so the clients can do what they want, they can not dive into the normal program landscape. However, the socket connection remains. So there is a socket connection without the event "connection" being called on the server.

Platform:

  • Device: PC, Notebook, Mac
  • OS: Windows, Linux, OSX
  • Browser: Safari (newest), Chrome (newest), Firefox (newest)

Additional context
Important, socket.io server running in google cloud run (docker container) and scale up/down up to the traffic, we had 250 connection at one container, a scale will happen at 150 open request.

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

Start with the server setup for dynamicNamespace, its connection handler, and the Redis adapter configuration shown in the issue. Reproduce the intermittent behavior across clustered servers and containers while simulating disconnects or scaling. Done means identifying why a client connection can remain without the server connection event and confirming the fix in that deployment setup.

Written by the indexing model from the issue text.

Assessment

Tech stack
google-cloud, javascript, node.js, redis
Domain
backend, distributed-systems, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.