树莓派3部署Flask-SSE示例无法连接事件流但Redis有活动
问题
在树莓派3上运行Flask-SSE官方示例代码,网站可正常加载,但页面会弹出提示:Failed to connect to event stream. Is Redis running?。Redis已处于运行状态,通过redis-cli monitor查看有如下活动记录(多次刷新页面产生,始终未收到消息):
1676659598.612265 [0 [::1]:58788] "SUBSCRIBE" "sse" 1676659616.141010 [0 [::1]:39662] "SUBSCRIBE" "sse" 1676659624.109693 [0 [::1]:54564] "SUBSCRIBE" "sse" 1676659627.603954 [0 [::1]:54578] "PUBLISH" "sse" "{\"data\": {\"message\": \"Hello!\"}, \"type\": \"greeting\"}" 1676659627.614501 [0 [::1]:58788] "UNSUBSCRIBE" "sse" 1676659627.621229 [0 [::1]:39662] "UNSUBSCRIBE" "sse" 1676659651.509510 [0 [::1]:53316] "SUBSCRIBE" "sse"
启动服务的命令:
$ sudo systemctl start nginx $ redis-server --daemonize yes $ gunicorn sse:app --worker-class gevent --workers=3 --bind 127.0.0.1:8000 --daemon
Python代码:
from flask import Flask, render_template from flask_sse import sse app = Flask(__name__) app.config["REDIS_URL"] = "redis://localhost" app.register_blueprint(sse, url_prefix='/stream') @app.route('/') def index(): return render_template("index.html") @app.route('/hello') def publish_hello(): sse.publish({"message": "Hello!"}, type='greeting') return "Message sent!"
index.html代码:
<!DOCTYPE html> <html> <head> <title>Flask-SSE Quickstart</title> </head> <body> <h1>Flask-SSE Quickstart</h1> <script> var source = new EventSource("{{ url_for('sse.stream') }}"); source.addEventListener('greeting', function(event) { var data = JSON.parse(event.data); alert("The server says " + data.message); }, false); source.addEventListener('error', function(event) { alert("Failed to connect to event stream. Is Redis running?"); }, false); </script> </body> </html>
解决方案
1. 修复Nginx反向代理配置
Nginx默认的缓冲配置会中断SSE长连接,需在对应location块中添加SSE支持配置:
location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 关键:禁用缓冲,保持长连接 proxy_buffering off; proxy_cache off; proxy_set_header Connection ''; proxy_http_version 1.1; chunked_transfer_encoding off; } location /stream { proxy_pass http://127.0.0.1:8000/stream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_buffering off; proxy_cache off; proxy_set_header Connection ''; proxy_http_version 1.1; chunked_transfer_encoding off; }
修改完成后重启Nginx:sudo systemctl restart nginx
2. 调整Gunicorn Worker数量
使用gevent多worker时,每个worker会独立订阅Redis,发布的消息只会被其中一个worker接收,其他worker的订阅会因超时而断开。测试阶段建议将worker数改为1:
gunicorn sse:app --worker-class gevent --workers=1 --bind 127.0.0.1:8000 --daemon
若需多worker支持,需使用Redis pub/sub的共享连接机制,或采用集群模式部署。
3. 验证EventSource请求状态
打开浏览器开发者工具(F12),切换到Network标签,查看EventSource对应的请求:
- 确认请求URL是否正确匹配
/stream路径 - 检查响应状态码是否为200
- 确认响应头包含
Content-Type: text/event-stream
4. 确认Redis连接有效性
通过redis-cli ping测试本地Redis连接,若返回PONG则连接正常。若Redis设置了密码,需修改Flask配置中的Redis URL:app.config["REDIS_URL"] = "redis://:your_password@localhost"
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

