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.

Sending a message to multiple rooms

See original GitHub issue

Is it possible to send (emit) a message to multiple rooms in such a way that if a client is a member of two rooms then he gets the message only once?

In the Socket.IO Node.js server this can be done as follows:

io.to('room1').to('room2').to('room3').emit('some event');

However socketio.emit seems to accept only one room as argument.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
nkgsvcommented, Jan 4, 2021

I think this feature would be useful, and moreover it would be coherent with the Node.js implementation.

In fact I would like to propose the following implementation for the case when the client list is stored in an in-memory structure:

class ExtendedBaseManager(BaseManager):
    def emit(self, event, data, namespace, room=None, skip_sid=None,
             callback=None, **kwargs):
        """Emit a message to a single client, a room, a list of rooms 
        or all the clients connected to the namespace.

        If a list of rooms is given then every socket that is at least
        in one of the rooms will get the event once (even if the socket
        is in two or more rooms)"""
        if namespace not in self.rooms:
            return
        
        if not isinstance(room, list):
            room = [room]

        to_rooms = set()
        for r in room:
            if r in self.rooms[namespace]:
                to_rooms.add(r)
        if len(to_rooms) == 0:
            return
            
        if not isinstance(skip_sid, list):
            skip_sid = [skip_sid]
        
        recipients = set()
        for r in to_rooms:
            recipients.update(self.get_participants(namespace, r))
        
        for sid in recipients:
            if sid not in skip_sid:
                if callback is not None:
                    id = self._generate_ack_id(sid, namespace, callback)
                else:
                    id = None
                self.server._emit_internal(sid, event, data, namespace, id)

Then the SocketIO server can be started via

import socketio
sio = socketio.Server(client_manager=ExtendedBaseManager())

or (in the case of flask_socketio)

from flask_socketio import SocketIO
sio = SocketIO(app, async_mode, client_manager=ExtendedBaseManager())

Once this is done, a message can be sent to multiple rooms as follows:

sio.emit('some_event', data={'hello': 'world'}, room=['room1', 'room2'], namespace='namespace')

Of course, this is limited to the case when the client list is stored in an in-memory structure.

0reactions
miguelgrinbergcommented, Jan 4, 2021

Right, unfortunately I cannot do it this way because it introduces a difference in how single and multiple servers are implemented. When I look at this I’ll have to find a solution that also works for multi-server deployments.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sending messages to multiple rooms using Socket.io?
Yes, it's possible to emit to multiple rooms altogether. From the tests: socket.on('emit', function(room){ ...
Read more >
Post a message to multiple channels - Microsoft Support
In a channel, select New conversation > Format. ; Choose the message type you want: New conversation or Announcement. ; Select Post in...
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 >
XEP-0045: Multi-User Chat - XMPP
Messages sent within multi-user chat rooms are of a special type "groupchat" and are addressed to the room itself (room@service), then reflected to...
Read more >
Sharing screen and broadcasting to breakout rooms
Click Broadcast, and select Broadcast Message. Enter your message and click the send icon . The message will appear for all participants 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