Is there a way we can get server side access to a list of clients connected to a room?
My guess is it would work something like this:
from flask.ext.socketio import rooms, room
...
print rooms()
> ["roomA", "roomB", "roomC"]
print room("roomA")
> ["4545256256","276827388"]
+1 on this
But I think you currently can achieve this today using the rooms dictionary from socketio:
socketio.rooms[<your-namespace>][<your-room>]. It appears to return a set of clients connected to it.
If you don't have a namespace use an empty string, like: socketio.rooms['']['foobar-room'].
@miguelgrinberg I'm willing to make a pull request for this one if you want, do you have any contributing guidelines / code style / etc?
Using internal variables of the extension is not a good idea, that forces me to keep them around in future releases. This is particularly important in this case, since the socketio.rooms structure is problematic and likely to dissappear in a future release when multiple worker servers are supported.
But I would be okay with exposing the list of rooms and the list of clients in a room through functions that I can later reimplement, so if you want to write that I'll accept it. As far as coding guidelines I'm not super strict, I'll review the pull request and let you know if I have any suggestions, but as a general advice, reasonable pep8 compliance is what I expect.
Thanks for the feedback, I think I can come up with something on this weekend.
(...) pep8 compliance is what I expect.
Yes, I think pep8 is universally accepted.
After giving it some thought, I've decided implementing this feature can complicate scalability. I intend to support multiple workers in the near future, and when having all the user information spread across multiple servers it is expensive to collect the list of clients in a room.
Is there anyway to do this today?
I have what I imagine is a fairly common use-case: if any clients in room: do something, else don't bother!
@markmnl well, presumably your application has access to a database, in which you can keep track of who's in what room. That's what I always recommend. You can also start looking into the internals of the Socket.IO server, with the disclaimer that things can change at any time, and then your code may stop working.
No database tracking which clients are currently connected.. Cool i'll have look at internals... Still think its a feature worth having! I'll make a PR if I come up with a good enough solution..
@markmnl there is no good solution, that is why I decided to not support that as a feature. The problem becomes complex if you take into account that you can have multiple servers, with the room participants randomly distributed among them.
I guess I'm missing something.. I thought if emit can find all the clients, why can't this do the same?
Yes, you are missing something. Emit cannot find all participants. It just emits to all the participants it knows about, then tells all the other servers in the cluster to do the same.
kk, I only need for this one socket-io server, so I will look into doing that.. I guess if you were to support that you would want it very explicit you are only getting clients in room _on this server_
That's a pretty big limitation, and in my opinion a deal breaker. If you implement it, you will not be able to scale out to two servers if one day you need to, because that will break your application.
Is there a way to see users in a room on the current server? Asking since in the case of a server restart, the disconnect event is never triggered server side -- would be good to iterate over rooms on a server restart and trigger the disconnect event to update the db.
Got it, in case anyone else is looking:
from flask_socketio import rooms
print(rooms(socket_id))
// prints [socket_id, room1, room2 ....]
And I store the mapping of rooms to socket id's in a different dictionary in a db and just check if the room in question is in the printed list.
@Divide-By-0 This method can only get the room where the current client is located, but how to get all the clients in the specified room, exmaple:
get_room_client([room_name]) # print [client1, client2, ...]
Most helpful comment
Got it, in case anyone else is looking:
And I store the mapping of rooms to socket id's in a different dictionary in a db and just check if the room in question is in the printed list.