Open philipn opened 12 years ago
It looks like we can also do this, which is a little awkward:
def broadcast_msg(server, tweet):
for socket in server.sockets.values():
if '/tweets' in socket:
socket['/tweets'].emit('tweet', tweet)
but better because we don't have to manually construct the packet object (which a user of gevent-socketio probably shouldn't ever have to worry about).
Awkward because I have to check to see if the namespace is in the socket before sending because of the order things happen in my example.
You really ought to use something like redis or zeromq for passing messages between sockets, because a typical production deployment will prefork multiple server instances, and you would otherwise have no visibility of sessions belonging to to another server instance.
This is true of emit(), etc as well, no? If using multiple servers the message won't be sent to everyone without using some kind of external message queue or other trickery.
But for many case the simple default single-server works great.
On Aug 1, 2012, at 3:18 PM, Daniel Swarbrickreply@reply.github.com wrote:
You really ought to use something like redis or zeromq for passing messages between sockets, because a typical production deployment will prefork multiple server instances, and you would otherwise have no visibility of sessions belonging to to another server instance.
Reply to this email directly or view it on GitHub: https://github.com/abourget/gevent-socketio/issues/67#issuecomment-7441873
Something like broadcast_event_not_me() is only capable of sending the event to all sockets connected to a single parent server. So if you have multiple server instances, they will need to subscribe to some sort of message queue like redis, and listen for messages from other server instances.
@dswarbrick Yeah, the SocketIO server API is by its very nature limited to a single server. The JS SocketIO server code has the notion of different stores, and you can use RedisStore to transparently interface with a redis backend - http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html. We should probably do something similar! (Would be a fun project!) But that's a larger issue.
@dswarbrick Tracking in #72
@philipn : it's funny to see we both worked on the same twitter implementation and ran across the same problem.
Maybe you'll want to see my modest contribution : https://github.com/ultrabug/geventweet
Whoa, that is funny! And we did it at like the exact same time, too.
I'm not sure about the session
global approach you use. I think using the server
object is more natural and more in line with what the JS implementation does. What do you think?
@philipn : sure I agree with you on the principle, that's why I also searched for a better solution and found this issue but I think @dswarbrick is right, we ought to use a proper message queuing layer rather than trying to hack the server. Maybe I'll take the time to implement this in geventweet
.
@philipn @ultrabug I'd like to discuss this more with you guys if you are interested. I have some spare time now. I think we should support scalable datastores for broadcasting like redis and zmq out of the box.
Currently, an individual socket can broadcast using the BroadcastMixin. But what if you want to spin up a greenlet -- independent of a particular connection -- and have it publish to all the sockets on the server? In my case I'm streaming some data from an API and want to send it to all the sockets. Here's what I'm doing:
Would this broadcast pattern be valuable to include as a method on the SocketIOServer class?