public
Last active

  • Download Gist
websocket_tornado_redis.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
"""
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()

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

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

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

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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.