question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

My discovery about the bug with Socket.rooms and how I found the current socket.rooms

See original GitHub issue

Bug description

Hi,

I am an enthusiast in Socket.io. At the moment, I would like to report a bug in version 2.x of socket.io, where the main impacted factor is rooms (which used to be io.sockets.rooms) but got changed in version 2.x. It is not deprecated and you can still access it, however through a very long chain of javascript object properties.

This error happens when I’m using a namespace.

I’ve dug into the socket source code and found a problem here. If you have installed node modules via npm (or yarn), you can find the file in ./node_modules/socket.io/lib/socket.js. In the function join

Socket.prototype.join = function(rooms, fn){
  ...
  var self = this;
  ...
  this.adapter.addAll(this.id, rooms, function(err){
  rooms.forEach(function (room) {
    console.log('each room in rooms----------', room);
    self.rooms[room] = room;  
    }
    console.log('This socket after setting rooms--------', self.adapter); // (****)
    ...
  });
  return this;

Note: All of the console.log() I mention are added by me.

If you take notice, in this function, we are adding each element of the rooms array to self.rooms. However, this is not the socket.rooms that we expect but a very different room. I’ll explain how we actually reach this room later.

Assume, in a real-life scenario, I want a socket to join after it has connected. Taking a look at the 'onconnect function in the socket.js file, which is always fired before the join function. Here is the code for the onconnect function:

Socket.prototype.onconnect = function(){
  ...
  console.log('in onconnect funtion', this.id); 
  this.join(this.id);
  ...
};

Here is where the problem arises. When we connect, we actually “join” this.id, thus making this.id become an unexpected room. From the console.log (****) that I added to the function join, you can see inside the property rooms:

rooms: 
     { '/namespace_name#x9Je6cweXBB5fp4eAAAB': Room { sockets: [Object], length: 1 },
     '/namespace_name#pMr_xrIEM2lSc182AAAC': Room { sockets: [Object], length: 1 },
     '/namespace_name#BscQZyK_gFrIL_2-AAAD': Room { sockets: [Object], length: 1 },
     '/namespace_name#C5WH4nJo_73ZVvGDAAAE': Room { sockets: [Object], length: 1 },
     room_name: Room { sockets: [Object], length: 1 } },

room_name is the name of the room that I used for socket.join(“room_name”)

You can see that I have a lot of extra, unexpected rooms that are automatically added when my socket connects.


How to find the current rooms

Assume you use a namespace

console.log('Room list that contains connected rooms', util.inspect(io.sockets.in('namespace_name').adapter.nsp.server.nsps['/namespace_name'].adapter.rooms, {showHidden: false, depth: 2, colors: true, }));

Ps

I have discovered this problem when I tried to find a list of all available connected rooms with socket.io. In versions before 1.0, we could do it with socket.rooms and we would have an array of room_name. However, in this 2.0 function, I cannot find any effective method that wouldn’t require a lot of steps to actually find a list of different rooms that have been connected. Can you give my a way to fetch all room names in the version 2.x (socket.rooms will not work)?

And should there be a way to filter rooms so that no duplication is made if there are many sockets connecting to the same room?

Tl,dr: Onconnect function in socket library adds redundant rooms to the room list by using the function join, and the rooms, which used to be found in socket.rooms, can be found in a different place.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
NicholasEwing-SBcommented, Apr 9, 2019

Has this been resolved yet? I don’t understand why having a client connect to a namespace creates a “room” of the user in that namespace.

@allicanseenow :

rooms: 
     { '/namespace_name#x9Je6cweXBB5fp4eAAAB': Room { sockets: [Object], length: 1 },
     '/namespace_name#pMr_xrIEM2lSc182AAAC': Room { sockets: [Object], length: 1 },
     '/namespace_name#BscQZyK_gFrIL_2-AAAD': Room { sockets: [Object], length: 1 },
     '/namespace_name#C5WH4nJo_73ZVvGDAAAE': Room { sockets: [Object], length: 1 },
     room_name: Room { sockets: [Object], length: 1 } },
room_name is the name of the room that I used for socket.join("room_name")

You can see that I have a lot of extra, unexpected rooms that are automatically added when my socket connects.

The socket.io documentation clearly states:

Within each namespace, you can also define arbitrary channels that sockets can join and leave.

My understanding is that namespaces contain rooms, but are not rooms themselves. Like a one-to-many relationship.

Rooms aren’t appearing under namespaces correctly either, which seems to contradict the documentation and what @spietrek87 mentioned about referencing the adapter.

In a app I’m working on, when a client joins a namespace called /project they automatically enter a room named after the project ID they’re viewing. Several of these projects exist such as “Project A” / “Project B” / etc.

When a client on Project A joins the namespace, this should create a room named “Project A” underneath the namespace of /project.

Here’s a code snippet:

server.js

const io = socket(server);

io.of('/project').on('connection', client => {
  client.on('join project', projId => {
    client.join(projId, () => {
      console.log(io.nsps['/project'].rooms); // returns an empty array
    });
  });
});

someReactComponent.js

componentDidMount() {
    this.socket = io('/project');
    this.socket.emit('join project', "Project A");
}

Inside server.js, console.log(io.nsps['/project'].rooms) should return ["Project A"], but contains [] instead.

Upon checking the adapter for the /project namespace by console.logging io.nsps['/project'].adapter.rooms, there are two rooms.

One is correctly named ‘Project A’ while another unexpected room is ‘/project#GUyI-6I3ktZusTJsAAAA’'.

It appears the second room should NOT be appearing as @allicanseenow stated.

    { 'Project A':
    Room {
      sockets: { '/project#GUyI-6I3ktZusTJsAAAA': true },
      length: 1 
    },
   '/project#GUyI-6I3ktZusTJsAAAA':
    Room {
      sockets: { '/project#GUyI-6I3ktZusTJsAAAA': true },
      length: 1 } 
    }

I’d love to see this bug fixed, otherwise it prevents the room / namespace distinction from existing and prevents this package from being useful.

If I’m just understanding socket.io incorrectly, please let me know. Thanks in advance!

0reactions
darrachequesnecommented, Feb 23, 2021

For future readers: as of Socket.IO v3, the socket.rooms attribute is basically a reference to the underlying adapter, which stores the relationships between Socket IDs and rooms.

Documentation: https://socket.io/docs/v3/rooms/#Implementation-details

Source:

Read more comments on GitHub >

github_iconTop Results From Across the Web

socket.io get rooms which socket is currently in - Stack Overflow
With 3.x Socket.rooms is Set now, which means that values in the rooms may only occur once. Structure example: Set( ...
Read more >
Rooms | Socket.IO
A room is an arbitrary channel that sockets can join and leave. It can be used to broadcast events to a subset of...
Read more >
FAQs - Matrix.org
What is Matrix? Matrix is an open standard for interoperable, decentralised, real-time communication over IP. It can be used to power Instant Messaging, ......
Read more >
How to Check Your Vacation Rental or Hotel Room for Hidden ...
Here are three ways to check to see if your vacation home rental - or your hotel room - has any hidden devices....
Read more >
How to spot hidden cameras in your Airbnb and hotels
Does your Airbnb or hotel have a hidden camera? Experts share tips for ... Should we be checking every room we stay in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found