python Socket.IO client for sending broadcast messages to TornadIO2 server

前端 未结 3 1444
滥情空心
滥情空心 2020-12-04 17:15

I am building a realtime web application. I want to be able to send broadcast messages from the server-side implementation of my python application.

相关标签:
3条回答
  • 2020-12-04 17:26

    I've recently written a very similar application on a similar setup, so I do have several insights.

    The proper way of doing what you need is to have a pub-sub backend. There's only so much you can do with simple ConnectionHandlers. Eventually, handling class-level sets of connections starts to get ugly (not to mention buggy).

    Ideally, you'd want to use something like Redis, with async bindings to tornado (check out brukva). That way you don't have to mess with registering clients to specific channels - Redis has all that out of the box.

    Essentially, you have something like this:

    class ConnectionHandler(SockJSConnection):
        def __init__(self, *args, **kwargs):
            super(ConnectionHandler, self).__init__(*args, **kwargs)
            self.client = brukva.Client()
            self.client.connect()
            self.client.subscribe('some_channel')
    
        def on_open(self, info):
            self.client.listen(self.on_chan_message)
    
        def on_message(self, msg):
            # this is a message broadcast from the client
            # handle it as necessary (this implementation ignores them)
            pass
    
        def on_chan_message(self, msg):
            # this is a message received from redis
            # send it to the client
            self.send(msg.body)
    
        def on_close(self):
            self.client.unsubscribe('text_stream')
            self.client.disconnect()
    

    Note that I used sockjs-tornado which I found to be much more stable than socket.io.

    Anyway, once you have this sort of setup, sending messages from any other client (such as Django, in your case) is as easy as opening a Redis connection (redis-py is a safe bet) and publishing a message:

    import redis
    r = redis.Redis()
    r.publish('text_channel', 'oh hai!')
    

    This answer turned out pretty long, so I went the extra mile and made a blog post out of it: http://blog.y3xz.com/blog/2012/06/08/a-modern-python-stack-for-a-real-time-web-application/

    0 讨论(0)
  • 2020-12-04 17:27

    If you're already using django, why not have a look at gevent-socketio.

    0 讨论(0)
  • 2020-12-04 17:37

    I write here, because it's difficult write in comments section. You can view examples for tornadoio2 in examples directory where you can find implementation of chat, and:

    class ChatConnection(tornadio2.conn.SocketConnection):
        # Class level variable
        participants = set()
    
        def on_open(self, info):
            self.send("Welcome from the server.")
            self.participants.add(self)
    
        def on_message(self, message):
            # Pong message back
            for p in self.participants:
                p.send(message)
    

    As you can see they implemented participants as set ))

    0 讨论(0)
提交回复
热议问题