Need help understanding Comet in Python (with Django)

后端 未结 3 1229
别那么骄傲
别那么骄傲 2020-12-08 04:37

After spending two entire days on this I\'m still finding it impossible to understand all the choices and configurations for Comet in Python. I\'ve read all the answers here

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-08 05:17

    Redis is relevant as a persistence layer that also supports native publish/subscribe. So instead of a situation where you are polling the db looking for new messages, you can subscribe to a channel, and have messages pushed out to you.

    I found a working example of the type of system you describe. The magic happens in the socketio view:

    def socketio(request):
        """The socket.io view."""
        io = request.environ['socketio']
        redis_sub = redis_client().pubsub()
        user = username(request.user)
    
        # Subscribe to incoming pubsub messages from redis.
        def subscriber(io):
            redis_sub.subscribe(room_channel())
            redis_client().publish(room_channel(), user + ' connected.')
            while io.connected():
                for message in redis_sub.listen():
                    if message['type'] == 'message':
                        io.send(message['data'])
        greenlet = Greenlet.spawn(subscriber, io)
    
        # Listen to incoming messages from client.
        while io.connected():
            message = io.recv()
            if message:
                redis_client().publish(room_channel(), user + ': ' + message[0])
    
        # Disconnected. Publish disconnect message and kill subscriber greenlet.
        redis_client().publish(room_channel(), user + ' disconnected')
        greenlet.throw(Greenlet.GreenletExit)
    
        return HttpResponse()
    

    Take the view step-by-step:

    1. Set up socket.io, get a redis client and the current user
    2. Use Gevent to register a "subscriber" - this takes incoming messages from Redis and forwards them on to the client browser.
    3. Run a "publisher" which takes messages from socket.io (from the user's browser) and pushes them into Redis
    4. Repeat until the socket disconnects

    The Redis Cookbook gives a little more detail on the Redis side, as well as discussing how you can persist messages.

    Regarding the rest of your question: Twisted is an event-based networking library, it could be considered an alternative to Gevent in this application. It's powerful and difficult to debug in my experience.

    Celery is a "distributed task queue" - basically, it lets you spread units of work out across multiple machines. The "distributed" angle means some sort of transport is required between the machines. Celery supports several types of transport, including RabbitMQ (and Redis too).

    In the context of your example, Celery would only be appropriate if you had to do some sort of costly processing on each message like scanning for profanity or something. Even still, something would have to initiate the Celery task, so there would need to be some code listening for the socket.io callback.

    (Just in case you weren't totally confused, Celery itself can be made to use Gevent as its underlying concurrency library.)

    Hope that helps!

提交回复
热议问题