Skip to content

Instantly share code, notes, and snippets.

@perrygeo
Last active March 17, 2018 10:43
Runs a simple pubsub listener which pushes to clients via sockjs
# -*- coding: utf-8 -*-
"""
Runs a simple pubsub listener which pushes to clients via sockjs
Based on https://gist.github.com/mrjoes/3284402
Eventually I'd like to have one redis connection listening on user_* channel
and pushing messages ONLY to that user's client. Currently it just sends
a message to everyone.
Setup:
virtualenv testenv
source testenv/bin/activate
pip install Tornado>=2.2 sockjs-tornado tornado-redis
# assumes redis-server is running on localhost:6379
Running:
python server.py
# open localhost:8089 in browser
redis-cli publish user_12 "Despite being for user_12, this message goes to everyone. Oops"
"""
import tornado.ioloop
import tornado.web
import tornadoredis
import sockjs.tornado
import logging
class BrokerConnection(sockjs.tornado.SockJSConnection):
clients = set()
def on_open(self, request):
logging.info('New client at %s' % request.ip)
import json
logging.info(json.dumps(request.__dict__, indent=2))
self.clients.add(self)
def on_close(self):
self.clients.remove(self)
@classmethod
def pubsub(cls, msg):
if msg.kind in ['message', 'pmessage']:
for c in cls.clients:
c.send(msg.body)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
# self.render('client.html')
# just to keep the example single-file
self.write("""<!DOCTYPE html>
<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://cdn.sockjs.org/sockjs-0.3.js"></script>
<script>
var conn;
$(function() {
conn = new SockJS("/push");
conn.onmessage = function(e) {
$('#messages').html('Got: ' + e.data);
}
var userid = Math.floor((Math.random()*10)+1); // rand b/t 1 and 10
$('#user').html(userid);
});
</script>
<h4> User <span id="user"></span></h4>
<div id="messages">
Listening for messages...
</div>
</body>
</html>""")
if __name__ == "__main__":
logging.getLogger().setLevel(logging.DEBUG)
port = 8090
key = "user_*"
rclient = tornadoredis.Client(host='localhost', port=6379)
rclient.connect()
rclient.psubscribe(key, lambda s: rclient.listen(BrokerConnection.pubsub))
BrokerRouter = sockjs.tornado.SockJSRouter(BrokerConnection, '/push')
app = tornado.web.Application(
[(r"/", IndexHandler)] + BrokerRouter.urls
)
app.listen(port)
logging.info('Listening on port %d for redis pubsub channel %s', port, key)
tornado.ioloop.IOLoop.instance().start()
@Pentusha
Copy link

I think it can be done like this: https://gist.github.com/Pentusha/5967328

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment