在Heroku部署Flask Websocket服务遇WebsocketMismatch错误求助
解决Heroku部署Flask-Sockets出现WebsocketMismatch错误问题
我用Godot制作回合制游戏,为防止作弊将服务部署在Heroku,选择Websocket方案并使用flask-sockets实现,但始终无法正常运行,Heroku日志中持续出现WebsocketMismatch错误。所有Websocket测试方法均无效,我确定是服务端存在问题。
Flask应用代码
from flask import Flask from flask_sockets import Sockets app = Flask(__name__) sockets = Sockets(app) @sockets.route('/reverse') def echo_socket(ws): while not ws.closed: message = ws.receive() ws.send(message[::-1]) @app.route('/') def hello(): return "Hello World!"
Heroku日志错误信息
2022-08-10T01:13:42.934964+00:00 app[web.1]: Traceback (most recent call last): 2022-08-10T01:13:42.934997+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gevent/pywsgi.py", line 999, in handle_one_response 2022-08-10T01:13:42.934998+00:00 app[web.1]: self.run_application() 2022-08-10T01:13:42.935002+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/geventwebsocket/handler.py", line 75, in run_application 2022-08-10T01:13:42.935002+00:00 app[web.1]: self.run_websocket() 2022-08-10T01:13:42.935004+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/geventwebsocket/handler.py", line 52, in run_websocket 2022-08-10T01:13:42.935005+00:00 app[web.1]: list(self.application(self.environ, lambda s, h, e=None: [])) 2022-08-10T01:13:42.935017+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2548, in __call__ 2022-08-10T01:13:42.935018+00:00 app[web.1]: return self.wsgi_app(environ, start_response) 2022-08-10T01:13:42.935029+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sockets.py", line 40, in __call__ 2022-08-10T01:13:42.935029+00:00 app[web.1]: handler, values = adapter.match() 2022-08-10T01:13:42.935039+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/werkzeug/routing/map.py", line 622, in match 2022-08-10T01:13:42.935040+00:00 app[web.1]: raise WebsocketMismatch() from None 2022-08-10T01:13:42.935067+00:00 app[web.1]: werkzeug.routing.exceptions.WebsocketMismatch: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. 2022-08-10T01:13:42.935181+00:00 app[web.1]: 2022-08-10T01:13:42Z {'REMOTE_ADDR': '10.1.31.248', 'REMOTE_PORT': '12800', 'HTTP_HOST': 'reversertesterheroku.herokuapp.com', (hidden keys: 33)} failed with WebsocketMismatch
问题原因及解决方案
1. 修正WSGI服务器配置
Flask自带的开发服务器不支持Websocket,必须使用兼容的服务器。修改Procfile为:
web: gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 app:app
同时确保requirements.txt包含以下依赖:
flask==2.2.2 flask-sockets==0.2.1 gevent==22.8.0 gevent-websocket==0.10.1 gunicorn==20.1.0
2. 强制使用WSS协议
Heroku强制使用HTTPS,Websocket请求必须用wss://而非ws://,否则会被重定向导致请求头丢失Websocket标识。客户端连接时务必使用wss://你的域名/reverse。
3. 替代方案:改用FastAPI+WebSocket
Flask-Sockets维护状态较差,FastAPI对Websocket有原生支持,部署更简单。示例代码:
from fastapi import FastAPI, WebSocket from fastapi.responses import HTMLResponse app = FastAPI() @app.websocket("/reverse") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() await websocket.send_text(data[::-1]) @app.get("/") async def root(): return HTMLResponse("Hello World!")
对应的Procfile配置:
web: uvicorn app:app --host 0.0.0.0 --port $PORT
requirements.txt依赖:
fastapi==0.95.2 uvicorn==0.22.0
内容的提问来源于stack exchange,提问作者user19731293
相关产品推荐
相关产品推荐

