68 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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
 | |
| 
 |