def build_sse_msg(message, event=None, id_=None): sse = Sse() if id_: sse.set_event_id(id_) sse.add_message(event, message) sse_msg = "".join(sse) return sse_msg
def eventstream(): sse = Sse() pubsub = redis.pubsub() while True: for event in event_types: pubsub.subscribe(event) with Timeout(TIMEOUT) as timeout: try: for message in pubsub.listen(): if message['type'] != "message": continue try: data = json.loads(message['data']) except ValueError: # broken json continue if 'site_id' not in data or data['site_id'] != SITE_ID: continue sse.add_message(message['channel'], str(message['data'])) for event in sse: yield str(event) sse.flush() timeout.cancel() timeout.start() # heartbeat, to detect if a user is disconnected except Timeout as t: if t is not timeout: # not our timeout raise yield ":\n\n" # heartbeat message finally: pubsub.close()
def build_sse_msg(message, event=None, id_=None): sse = Sse() if id_: sse.set_event_id(id_) sse.add_message(event, message) sse_msg = "".join(sse) print("YYYYYYYYYYY: {}".format(sse_msg)) return sse_msg
def dispatch(self, request, *args, **kwargs): self.sse = Sse() self.request = request self.args = args self.kwargs = kwargs response = StreamingHttpResponse(self._iterator(), content_type="text/event-stream") response['Cache-Control'] = 'no-cache' response['Software'] = 'django-sse' return response
def test_add_message__list(self): sse = Sse() sse.add_message("foo", ["foo-message"]) sse.add_message("bar", ["bar-message"]) self.assertEqual(list(sse), [ 'retry: 2000\n\n', 'event: foo\n', 'data: foo-message\n', '\n', 'event: bar\n', 'data: bar-message\n', '\n' ])
def dispatch(self, request, *args, **kwargs): self.sse = Sse() # Check if there is a channel extension in kwargs. # This may be used to separate events of the same kind # by some identifier (some object id, for example) channel_extension = kwargs.get('channel_extension', '') if channel_extension: self.channel = '%s/%s' % (self.channel, channel_extension) response = HttpResponse(self._generate_content(), content_type="text/event-stream") response['Cache-Control'] = 'no-cache' response['X-Accel-Buffering'] = 'no' response['Software'] = 'django-sse-wrapper' return response
def test_add_message__simple_text_split(self): sse = Sse() sse.add_message("foo", "foo\nmessage") sse.add_message("bar", "bar\nmessage") self.assertEqual(list(sse), [ 'retry: 2000\n\n', 'event: foo\n', 'data: foo\n', 'data: message\n', '\n', 'event: bar\n', 'data: bar\n', 'data: message\n', '\n' ])
def test_add_message__simple_text(self): sse = Sse() sse.add_message("foo", "foo-message") sse.add_message("bar", "bar-message") self.assertEqual(to_unicode(sse), "retry: 2000\n\nevent: foo\ndata: " "foo-message\n\nevent: bar\ndata: " "bar-message\n\n") self.assertEqual(list(sse), [ 'retry: 2000\n\n', 'event: foo\n', 'data: foo-message\n', '\n', 'event: bar\n', 'data: bar-message\n', '\n' ])
def dispatch(self, request, *args, **kwargs): # This is basically the same method as in RedisQueueView.dispatch, # which should be a BaseSseView.dispatch. The only thing we modify # here is an extra header, called X-Accel-Buffering, which disables # buffering of this view by a webserver, for example nginx needs # that: http://wiki.nginx.org/X-accel#X-Accel-Buffering . # Also, we close db connection, as it won't be needed here. self.sse = Sse() self.request = request self.args = args self.kwargs = kwargs from django import db db.close_connection() response = HttpResponse(self._iterator(), content_type="text/event-stream") response['Cache-Control'] = 'no-cache' response['Software'] = 'django-sse' response['X-Accel-Buffering'] = 'no' return response
def send_message(cls, msg): """ Sends a message to all live connections """ id = str(uuid.uuid4()) event, data = json.loads(msg.body) sse = Sse() sse.set_event_id(id) sse.add_message(event, data) message = ''.join(sse) cls._cache.append({ 'id': id, 'channel': msg.channel, 'body': ''.join(sse), }) if len(cls._cache) > cls._cache_size: cls._cache = cls._cache[-cls._cache_size:] clients = cls._channels.get(msg.channel, []) logger.info('Sending %s "%s" to channel %s for %s clients' % (event, data, msg.channel, len(clients))) for client_id in clients: client = cls._connections[client_id] client.on_message(message)
def initialize(self): self.set_header('Content-Type', 'text/event-stream') self.set_header('Cache-Control', 'no-cache') self.set_header('X-Accel-Buffering', 'no') self.sse = Sse() self.stream = True
def __init__(self, backend, channel): """Initialise PublishSubscribe instance and channel.""" self.sse = Sse() self.backend = backend self.backend.subscribe(channel)
def test_flush(self): sse = Sse() sse.add_message("foo", "bar") sse.flush() self.assertEqual(len(sse._buffer), 0)
def test_dinamic_methods(self): sse = Sse() sse.add_event_foo(text="bar") self.assertEqual(list(sse), ['retry: 2000\n\n', 'event: foo\n', 'data: bar\n', '\n'])
def test_constructor(self): self.assertEqual(list(Sse()), ['retry: 2000\n\n']) self.assertEqual(list(Sse(default_retry=1000)), ['retry: 1000\n\n'])
def test_flush_on_iter(self): sse = Sse() sse.add_message("foo", "bar") self.assertEqual(list(sse), ['retry: 2000\n\n', 'event: foo\n', 'data: bar\n', '\n']) self.assertEqual(list(sse), [])