Skip to content

Instantly share code, notes, and snippets.

@nobane
Last active August 29, 2015 14:18
Show Gist options
  • Save nobane/99cca99393d4e58ffb05 to your computer and use it in GitHub Desktop.
Save nobane/99cca99393d4e58ffb05 to your computer and use it in GitHub Desktop.
#!/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