Flask-SocketIO结合蓝图使用时客户端无法接收服务端emit消息
Flask-SocketIO在工厂模式+蓝图架构下客户端无法接收emit消息
此前曾提过类似问题,现单独发帖求助:在采用工厂应用原则构建且使用蓝图的Flask应用中集成Flask-SocketIO,Socket连接正常(connect事件已触发),但手动调用含emit()的函数时,客户端无法接收消息。
简化代码示例
init.py
from flask import Flask from flask_socketio import SocketIO import os gv_socketio = SocketIO(logger=True, engineio_logger=True) def create_app(): # instance_relative_config=True --> 实例文件夹位于主目录(此处为'spotr')外 app = Flask(__name__, instance_relative_config=True) # 默认配置,'spotr.sqlite'将存放在实例文件夹中 app.config.from_mapping( SECRET_KEY='dev', DATABASE=os.path.join(app.instance_path, 'spotr.sqlite'), ) # 用'config.py'中的值覆盖默认配置(不存在则静默失败) app.config.from_pyfile('config.py', silent=True) # 初始化SocketIO扩展 gv_socketio.init_app(app) # 确保实例文件夹存在 try: os.makedirs(app.instance_path) except OSError: pass with app.app_context(): # 注册蓝图 from . import watchlist, home, database app.register_blueprint(watchlist.bp_watchlist) app.register_blueprint(home.bp_home) app.register_blueprint(database.bp_database) return app
watchlist.py
from flask import Blueprint, request, render_template from flask_socketio import emit from . import gv_socketio bp_watchlist = Blueprint('watchlist', __name__, url_prefix="/watchlist") def sendStatusViaSocket(note): gv_socketio.emit('updateStatus', {"data": note}, namespace='/watchlist') @bp_watchlist.route("/", methods=["GET","POST"]) def watchlist_main(): args = request.args # 页面加载逻辑 if request.method == "GET" and not ("addArtist" in args): sendStatusViaSocket("11111111111111") return render_template('watchlist.html')
watchlist.html
{% extends 'base.html' %} {% block title %} Watchlist {% endblock %} {% block content %} <!-- socketio 接口 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js"></script> <script> socket = io(); socket.connect('http://' + document.domain + ':' + location.port + '/watchlist'); socket.on('updateStatus',function(data){ console.log('HEY'); // console.log(data.data); }) socket.on('connect',function(){ console.log('CONNECT'); }) socket.on('message',function(msg){ console.log("MESSAGE"); }) </script> <!-- 其他页面内容 --> .... {% endblock %}
问题现象
预期触发watchlist_main()函数时,sendStatusViaSocket()会向客户端(watchlist.html)发送updateStatus事件,但客户端无任何响应,仅控制台打印CONNECT,浏览器调试中updateStatus和message事件均未触发。
Socket日志
127.0.0.1 - - [21/Aug/2022 13:29:35] "GET /watchlist/ HTTP/1.1" 200 - 127.0.0.1 - - [21/Aug/2022 13:29:35] "GET /static/style.css HTTP/1.1" 304 - **The WebSocket transport is not available, you must install a WebSocket server that is compatible with your async mode to enable it. See the documentation for details. (further occurrences of this error will be logged with level INFO)** bYHyaOm5DEHy1S5XAAAA: Sending packet OPEN data {'sid': 'bYHyaOm5DEHy1S5XAAAA', 'upgrades': [], 'pingTimeout': 20000, 'pingInterval': 25000} 127.0.0.1 - - [21/Aug/2022 13:29:35] "GET /socket.io/?EIO=4&transport=polling&t=OB0AbE6 HTTP/1.1" 200 - bYHyaOm5DEHy1S5XAAAA: Received packet MESSAGE data 0 CONNNNECT bYHyaOm5DEHy1S5XAAAA: Sending packet MESSAGE data 0{"sid":"Q941dFU3MYnD-ydkAAAB"} 127.0.0.1 - - [21/Aug/2022 13:29:35] "GET /socket.io/?EIO=4&transport=polling&t=OB0AbHH&sid=bYHyaOm5DEHy1S5XAAAA HTTP/1.1" 200 - 127.0.0.1 - - [21/Aug/2022 13:29:35] "POST /socket.io/?EIO=4&transport=polling&t=OB0AbHG&sid=bYHyaOm5DEHy1S5XAAAA HTTP/1.1" 200 - bYHyaOm5DEHy1S5XAAAA: Received packet MESSAGE data 2["done"] received event "done" from Q941dFU3MYnD-ydkAAAB [/] 127.0.0.1 - - [21/Aug/2022 13:29:35] "POST /socket.io/?EIO=4&transport=polling&t=OB0AbI0&sid=bYHyaOm5DEHy1S5XAAAA HTTP/1.1" 200 -
已尝试的解决
参考'Flask-SocketIO-Chat'仓库排查问题,尝试安装gevent-websocket和eventlet,但仍存在'WebSocket传输不可用'的警告,问题未解决。
内容的提问来源于stack exchange,提问作者user3592897
相关产品推荐
相关产品推荐

