Redis 发布订阅给出错误结果
Redis在处理SSE事件时给出的结果不正确。
下面这段代码在Python命令行界面中是可以正常工作的:
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
比如,当我从Redis终端执行 PUBLISH chat "hello"
时,它返回的结果是 'data: hello\n\n'
。
但是在Bottle.py中,下面这段代码却不行:
@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>
"""
当我访问 127.0.0.1:8000/test
时,每隔几秒我看到的内容是:
1
1
1
1
1
1
1
1
...
而我应该看到的是:
hello
hi
howdy
...
如果我把它改成:
@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('/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
这样就能正常工作,但这不是我需要的,因为这是一个返回当前时间(以毫秒为单位)的函数……
既然在Python命令行界面中没有问题,那这里到底出了什么错呢?我一直在想办法解决这个看似简单的问题……
1 个回答
1
哎呀!这个问题的解决办法其实很简单。
我需要把
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
return 'data: %s\n\n' % message['data']
改成
def stream():
pubsub = reds.pubsub()
pubsub.subscribe('chat')
for message in pubsub.listen():
yield 'data: %s\n\n' % message['data']
简单来说,就是把 return
改成 yield
。不过奇怪的是,最开始 yield 是不管用的……