Reputation: 67
Redis is giving wrong results to SSE event handler.
The following code works in the Python CLI
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
Returning for example 'data: hello\n\n'
When I PUBLISH chat "hello"
from the Redis terminal.
But the following in Bottle.py doesn't
@get('/stream')
def stream():
response.content_type = 'text/event-stream'
response.set_header('Cache-Control', 'no-cache')
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
@get('/test')
def test():
return """
<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource('/stream');
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
"""
When I visit 127.0.0.1:8000/test
I see the following every few seconds
1
1
1
1
1
1
1
1
...
Where I should be seeing instead
hello
hi
howdy
...
If I change
@get('/stream')
def stream():
response.content_type = 'text/event-stream'
response.set_header('Cache-Control', 'no-cache')
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
To
@get('/stream')
def stream():
response.content_type = 'text/event-stream'
response.set_header('Cache-Control', 'no-cache')
now = datetime.datetime.now().time().replace(microsecond=0)
return "data: %s\n\n"%now
it works, but that's not what I need, it is a function that returns the current time in milliseconds ..
Given that it works without problems in the Python CLI what can be wrong here then? I'm banging my head trying to solve something that should be easy to do ..
Upvotes: 0
Views: 521
Reputation: 67
Duh! The solution was a simple one.
I had to change
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
to
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
yield 'data: %s\n\n' % message['data']
Basically change return
to yield
. The weird thing though, is that yield didn't work in the first place..
Upvotes: 1