Instantly share code, notes, and snippets.

Embed
What would you like to do?
"""
This is a simple example of WebSocket + Tornado + Redis Pub/Sub usage.
Do not forget to replace YOURSERVER by the correct value.
Keep in mind that you need the *very latest* version of your web browser.
You also need to add Jacob Kristhammar's websocket implementation to Tornado:
Grab it here:
http://gist.github.com/526746
Or clone my fork of Tornado with websocket included:
http://github.com/pelletier/tornado
Oh and the Pub/Sub protocol is only available in Redis 2.0.0:
http://code.google.com/p/redis/downloads/detail?name=redis-2.0.0-rc4.tar.gz
Tested with Chrome 6.0.490.1 dev under OS X.
For questions / feedback / coffee -> @kizlum or thomas@pelletier.im.
Have fun.
"""
import threading
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import redis
# This is ugly but I did not want to create multiple files for a so trivial
# example.
TEMPLATE = """
<!DOCTYPE>
<html>
<head>
<title>Sample test</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
</head>
<body>
<h1>Hello world</h1>
<form method='POST' action='./'>
<textarea name='data' id="data"></textarea>
<div><input type='submit'></div>
</form>
<div id="log"></div>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$('form').submit(function(event){
var value = $('#data').val();
$.post("./", { data: value }, function(data){
$("#data").val('');
});
return false;
});
if ("WebSocket" in window) {
var ws = new WebSocket("ws://YOURSERVER:8888/realtime/");
ws.onopen = function() {};
ws.onmessage = function (evt) {
var received_msg = evt.data;
var html = $("#log").html();
html += "<p>"+received_msg+"</p>";
$("#log").html(html);
};
ws.onclose = function() {};
} else {
alert("WebSocket not supported");
}
});
</script>
</body>
</html>
"""
LISTENERS = []
def redis_listener():
r = redis.Redis(host='YOURSERVER', db=2)
r.subscribe('test_realtime')
for message in r.listen():
for element in LISTENERS:
element.write_message(unicode(message['data']))
class NewMsgHandler(tornado.web.RequestHandler):
def get(self):
self.write(TEMPLATE)
def post(self):
data = self.request.arguments['data'][0]
r = redis.Redis(host='YOURSERVER', db=2)
r.publish('test_realtime', data)
class RealtimeHandler(tornado.websocket.WebSocketHandler):
def open(self):
LISTENERS.append(self)
def on_message(self, message):
pass
def on_close(self):
LISTENERS.remove(self)
settings = {
'auto_reload': True,
}
application = tornado.web.Application([
(r'/', NewMsgHandler),
(r'/realtime/', RealtimeHandler),
], **settings)
if __name__ == "__main__":
threading.Thread(target=redis_listener).start()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
@readysetawesome

This comment has been minimized.

readysetawesome commented Feb 23, 2011

Thank you so much! Exactly what I was looking for....

@peterbe

This comment has been minimized.

peterbe commented Oct 31, 2011

I love the simplicity of it. Only problem is that it doesn't kill the thread on Ctrl-C on the command line.

@lbolla

This comment has been minimized.

lbolla commented Feb 11, 2013

I've forked this gist and fixed some issues: https://gist.github.com/lbolla/4754600

@gnpkrish

This comment has been minimized.

gnpkrish commented Jan 15, 2014

New way of Tornado + Websocket + Simple EE;; https://gist.github.com/gnpkrish/8435287

@cuteonion

This comment has been minimized.

cuteonion commented May 15, 2016

so cool!

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