Adam Barak
Adam Barak

Reputation: 67

Redis pubsub giving wrong results

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

Answers (1)

Adam Barak
Adam Barak

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

Related Questions