Last active
August 29, 2015 14:18
-
-
Save nobane/99cca99393d4e58ffb05 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import datetime | |
import flask | |
import json | |
import thread | |
import time | |
import uuid | |
from Queue import Queue | |
class PubSub(object): | |
def __init__(self): | |
self.messages = Queue() | |
def listen(self): | |
return self.messages.get(block=True, timeout=None) | |
def publish(self, message): | |
self.messages.put_nowait(message) | |
app = flask.Flask(__name__) | |
app.secret_key = 'asdf' | |
heartbeat_interval = 60 # seconds | |
users = {} | |
def heartbeat(delay): | |
while True: | |
for user in users: | |
users[user].publish('heartbeat') | |
time.sleep(delay) | |
thread.start_new_thread(heartbeat, (heartbeat_interval,)) | |
def event_stream(id): | |
pubsub = users[id] | |
connected = True | |
# TODO: handle client disconnection. | |
while connected: | |
print 'Waiting for a message to send to %s' % id | |
message = pubsub.listen() | |
print 'Sending %s to %s' % (message, id) | |
try: | |
yield 'data: %s\n\n' % message | |
except: | |
print 'Error sending message to %s' % id | |
connected = False | |
print 'Stream %s is disconnected' % id | |
@app.route('/login', methods=['GET', 'POST']) | |
def login(): | |
if flask.request.method == 'POST': | |
flask.session['user'] = flask.request.form['user'] | |
return flask.redirect('/') | |
return '<form action="" method="post">user: <input name="user">' | |
@app.route('/stream') | |
def stream(): | |
id = uuid.uuid4().get_hex() | |
users[id] = PubSub() | |
return flask.Response(event_stream(id), | |
mimetype="text/event-stream") | |
@app.route('/test/<message>') | |
def test(message): | |
print users | |
for user in users: | |
print user | |
users[user].publish(message) | |
return '' | |
@app.route('/') | |
def home(): | |
if 'user' not in flask.session: | |
return flask.redirect('/login') | |
return """ | |
<!doctype html> | |
<title>chat</title> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<style>body { max-width: 500px; margin: auto; padding: 1em; background: black; color: #fff; font: 16px/1.6 menlo, monospace; }</style> | |
<p><b>hi, %s!</b></p> | |
<p>Message: <input id="in" /></p> | |
<pre id="out"></pre> | |
<script> | |
var source = new EventSource('/stream'); | |
var out = document.getElementById('out'); | |
source.onmessage = function(e) { | |
// XSS in chat is fun | |
console.log(e) | |
out.innerHTML = e.data + '\\n' + out.innerHTML; | |
}; | |
source.onerror = function(e) { | |
console.log(e); | |
} | |
source.onopen = function(e) { | |
console.log(e); | |
} | |
$('#in').keyup(function(e){ | |
if (e.keyCode == 13) { | |
$.post('/post', {'message': $(this).val()}); | |
$(this).val(''); | |
} | |
}); | |
</script> | |
""" % flask.session['user'] | |
if __name__ == '__main__': | |
app.debug = True | |
app.run(threaded=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment