Files
twitter-project/eca/sse.py

68 lines
1.9 KiB
Python

import queue
from collections import namedtuple
from . import httpd
PendingEvent = namedtuple('PendingEvent', ['data', 'name', 'id'])
class ServerSideEvents(httpd.Handler):
"""
Base class for server side events. See the specification of the W3C
at http://dev.w3.org/html5/eventsource/
This class handles decoupling through the default Queue. Events can be
posted for transmission by using send_event.
"""
def __init__(self, request):
super().__init__(request)
self.queue = queue.Queue()
def send_event(self, data, name=None, id=None):
self.queue.put(PendingEvent(data, name, id))
def go_subscribe(self):
pass
def go_unsubscribe(self):
pass
def handle_GET(self):
self.go_subscribe()
# Send HTTP headers:
self.request.send_response(200)
self.request.send_header("Content-type", "text/event-stream")
self.request.end_headers()
done = False
while not done:
event = self.queue.get()
if event == None:
done = True
else:
done = not self._send_message(event)
self.go_unsubscribe()
def _send_message(self, event):
try:
if event.id is not None:
id_line = "id: {}\n".format(event.id)
self.request.wfile.write(id_line.encode('utf-8'))
if event.name is not None:
event_line = "event: {}\n".format(event.name)
self.request.wfile.write(event_line.encode('utf-8'))
data_line = "data: {}\n".format(event.data)
self.request.wfile.write(data_line.encode('utf-8'))
self.request.wfile.write("\n".encode('utf-8'))
self.request.wfile.flush()
return True
except IOError:
return False