Socket.io opening a second connection

Viewed 26

Requirements

I have the following user requirements:

  1. Document A can be edited in real-time by n users
  2. User A can edit the document A and everyone connected to document A should see changes in real time
  3. The same goes for documents B, C, D, ..., n

I'm currently using socket.io in an express server to handle the real-time communication. The logic (reduced to a minimal reproducible example) is as follow:

  1. As soon as user opens document A, he joins a room by emitting an event join:room to the websocket server
  2. websocket server attaches the user to room document A
  3. user A writes something on document A, user B will receive the updates in real-time
  4. user B leaves document A, he emits an event leave:room to websocket server

Minimum reproducible example

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
  cors: {
    origin: "*"
  }
});

io.on('connection', (socket) => {
  socket.on('join:room', (data) => {
    console.log(`Joined room: ${data.roomId}`);

    socket.join(data.roomId);
  });

  socket.on('text:insert', (data) => {
    console.log(`Text inserted: ${data.roomId}`);

    socket.to(data.roomId).emit('text:inserted', data);
  });

  socket.on('leave:room' , (data) => {
    console.log('left room: ' + data.roomId);
    socket.leave(data.roomId);
  });
})

The code on the client is as follow (reproduced to a minimal reproducible example):

// main.js
import { io } from "socket.io-client";

window.io = io;
console.log('opened connection');
window.monacoSocket = io(process.env.MIX_WEBSOCKET_SERVER_URL);

// custom.js
function onTextInserted({ user, event }) {
  console.log('Text have been inserted: ' + event);
}

document.querySelectorAll('.files')
  .forEach((item) => {
    item.dblclick(() => {
      window.monacoSocket.removeAllListeners();

      window.monacoSocket.on('text:inserted', ({ event, user }) => onTextInserted({ user, event }));
    });
  });

This codes works great when we are working in the same document

The problem

The problem starts when I move from document A to document B. Whenever I open my page and visit only document A, I can see that only a single websocket connection was opened and everything works as expected (from both user A and user B perspective):

enter image description here

Now, if I follow the following steps:

  1. as user A I open document A
  2. as user B I open document A
  3. as user A I make a change in document A
  4. as user A I switch to document B
  5. as user A I make changes to document B
  6. as user B I see a new connection opening in my network tab

As soon as this new connection is opened, user A and user B will not be receiving changes anymore

enter image description here

Questions

I have a couple of questions to help me understand what exactly is going on here.

  1. When I add new listeners to a socket.io-client instance, should the socket.io library open a new connection as it is doing right now?

  2. What exactly is causing the new connection to be opened? Is it safe to assume that if no new connection would be open, the code should work as intended - the console.log in onTextInserted function should print?

  3. On my anonymous function on dbclick, should I see remove all listeners?

I highly appreciate anyone taking the time to answer these questions.

0 Answers
Related