Django / gevent socket.IO con redis pubsub. ¿Dónde pongo las cosas?

Tengo una secuencia de comandos de Python aislada que simplemente captura los datos de la API de transmisión de Twitter y luego en la recepción de cada mensaje, utilizando redis pubsub que publica en el canal “tweets”. Aquí está ese guión:

def main(): username = "username" password = "password" track_list = ["apple", "microsoft", "google"] with tweetstream.FilterStream(username, password, track=track_list) as stream: for tweet in stream: text = tweet["text"] user = tweet["user"]["screen_name"] message = {"text": text, "user": user} db.publish("tweets", message) if __name__ == '__main__': try: print "Started..." main() except KeyboardInterrupt: print '\nGoodbye!' 

La implementación de socket.io del lado del servidor se realiza utilizando django-socketio (basado en gevent-socketio) https://github.com/stephenmcd/django-socketio que simplemente proporciona algunos decoradores auxiliares así como un método de broadcast_channel. Debido a que está hecho en django, simplemente puse este código en views.py simplemente para que se importen. Mi código de views.py:

 def index(request): return render_to_response("twitter_app/index.html", { }, context_instance=RequestContext(request)) def _listen(socket): db = redis.Redis(host="localhost", port=6379, db=0) client = db.pubsub() client.subscribe("tweets") tweets = client.listen() while True: tweet = tweets.next() tweet_data = ast.literal_eval(tweet["data"]) message = {"text": tweet_data["text"], "user": tweet_data["user"], "type": "tweet"} socket.broadcast_channel(message) @on_subscribe(channel="livestream") def subscribe(request, socket, context, channel): g = Greenlet.spawn(_listen, socket) 

El lado del cliente socket.io JavaScript simplemente se conecta y se suscribe al canal “livestream” y captura cualquier mensaje recibido en ese canal:

 var socket = new io.Socket(); socket.connect(); socket.on('connect', function() { socket.subscribe("livestream"); }); socket.on('message', function(data) { console.log(data); }); 

El problema obvio con este código es que cada vez que se abre una nueva ventana de usuario o navegador en la página, se genera un nuevo método _listen y los tweets se suscriben y difunden para cada usuario, lo que da como resultado que se reciban mensajes duplicados en el cliente. Mi pregunta es, ¿dónde estaría el lugar adecuado para poner el método _listen de modo que solo se cree una vez, independientemente del número de clientes? Además, teniendo en cuenta que el método broadcast_channel es un método de una instancia de socket.

El problema era que estaba usando socket.broadcast_channel cuando debería haber estado usando socket.send.