-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a lib for server sent events. bump version.
- Loading branch information
Showing
2 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
""" | ||
domonic.webapi.messaging | ||
==================================== | ||
https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API | ||
""" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
""" | ||
domonic.webapi.sse | ||
==================================== | ||
https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events | ||
TODO - consider a blocking verison? | ||
TODO - port one of the polyfills? | ||
https://github.com/EventSource/eventsource/blob/master/lib/eventsource.js | ||
https://github.com/remy/polyfills/blob/master/EventSource.js | ||
https://github.com/Yaffle/EventSource/blob/master/src/eventsource.js | ||
# TESTING - useage example... clone this and point at the stream | ||
# https://github.com/byteface/SSELoggerDemo | ||
""" | ||
|
||
from domonic.events import MessageEvent, EventTarget | ||
|
||
|
||
class EventSource(EventTarget): | ||
# https://developer.mozilla.org/en-US/docs/Web/API/EventSource | ||
|
||
CONNECTING = 0 | ||
OPEN = 1 | ||
CLOSED = 2 | ||
|
||
def __init__(self, url, eventSourceInitDict=None, **kwargs): | ||
""" | ||
The EventSource interface provides the ability to asynchronously receive messages from a server using simple push paradigm. | ||
""" | ||
eventSourceInitDict = eventSourceInitDict or kwargs | ||
super().__init__() | ||
self._url = url | ||
self._readyState = EventSource.CLOSED | ||
self._withCredentials = eventSourceInitDict.get('withCredentials', False) | ||
self._lastEventId = eventSourceInitDict.get('lastEventId', None) | ||
|
||
self._onmessage = eventSourceInitDict.get('onmessage', None) | ||
self._onerror = eventSourceInitDict.get('onerror', None) | ||
self._onopen = eventSourceInitDict.get('onopen', None) | ||
self._onreadystatechange = eventSourceInitDict.get('onreadystatechange', None) | ||
|
||
# from sseclient import SSEClient | ||
# messages = SSEClient(url) | ||
# self._readyState = EventSource.OPEN | ||
# for msg in messages: | ||
# self.onmessage(MessageEvent(msg)) | ||
# print(msg) | ||
# self._readyState = EventSource.CLOSED | ||
|
||
def _do_stuff(): | ||
from sseclient import SSEClient | ||
messages = SSEClient(url) | ||
self._readyState = EventSource.OPEN | ||
# self.onopen(MessageEvent(messages)) | ||
for msg in messages: | ||
self.onmessage(MessageEvent(msg)) | ||
# print(msg) | ||
self._readyState = EventSource.CLOSED | ||
|
||
# TODO - use a thread or it will block the main thread | ||
import threading | ||
|
||
# def _on_message(msg): | ||
# self.onmessage(MessageEvent(msg)) | ||
# print(msg) | ||
# self._readyState = EventSource.OPEN | ||
|
||
# def _on_error(err): | ||
# self.onerror(err) | ||
# self._readyState = EventSource.CLOSED | ||
|
||
# def _on_open(msg): | ||
# self.onopen(msg) | ||
# self._readyState = EventSource.OPEN | ||
|
||
# def _on_ready_state_change(msg): | ||
# self.onreadystatechange(msg) | ||
# self._readyState = EventSource.OPEN | ||
|
||
# def _on_close(msg): | ||
# self.onclose(msg) | ||
# self._readyState = EventSource.CLOSED | ||
|
||
self._thread = threading.Thread(target=_do_stuff) | ||
self._thread.start() | ||
|
||
# print('this is so cool!') | ||
|
||
@property | ||
def readyState(self): | ||
""" A number representing the state of the connection. | ||
Possible values are CONNECTING (0), OPEN (1), or CLOSED (2). """ | ||
return self._readyState | ||
|
||
@property | ||
def url(self): | ||
""" A DOMString representing the URL of the source. """ | ||
return self._url | ||
|
||
@property | ||
def withCredentials(self): | ||
""" A boolean value indicating whether the EventSource object was | ||
instantiated with cross-origin (CORS) credentials | ||
set (true), or not (false, the default). """ | ||
return self._withCredentials | ||
|
||
def close(self): | ||
""" Closes the connection to the EventSource. """ | ||
self._readyState = EventSource.CLOSED | ||
# close the thread | ||
self._thread.join() | ||
self._thread = None | ||
|
||
def onreadystatechange(self, event): | ||
""" Called when the state of the connection changes. """ | ||
pass | ||
|
||
def onmessage(self, event): | ||
""" Called when a message is received. """ | ||
if self._onmessage is not None: | ||
self._onmessage(event) | ||
|
||
def onerror(self, event): | ||
""" Called when an error occurs. """ | ||
pass | ||
|
||
def onopen(self, event): | ||
""" Called when the connection is established. """ | ||
pass | ||
|
||
# ''' | ||
# NOTE - if we write custom one rather than use lib... | ||
# def _poll(self): | ||
|
||
# if self._readyState == EventSource.CLOSED: | ||
# return | ||
|
||
# url = 'http://domain.com/events' | ||
# headers = { | ||
# 'Accept': 'text/event-stream', | ||
# 'Cache-Control': 'no-cache', | ||
# 'X-requested-with': 'XMLHttpRequest' | ||
# } | ||
# if self._lastEventId != None: | ||
# headers['Last-Event-ID'] = self._lastEventId | ||
|
||
# import requests | ||
# response = requests.get(url, stream=True, headers=headers) | ||
# # TODO - parse repsonse | ||
# ''' |