我编写了一个使用flask-socketio的Flask应用。我在端口8000上运行flask应用程序,并在端口3000(react-webpack)上分别运行客户端应用程序。它在开发模式下(烧瓶中提供了Web服务器)可以完美地工作。但是,当尝试使用uwsgi运行时,出现了问题。这些问题和配置将在下面详细说明。
wsgi.py (保持不变)
from cloud_app import app, sock
if __name__ == "__main__":
sock.run(app,host='0.0.0.0', debug=True, port=8000)
__ init __。py (保持不变)
from flask import Flask
from flask_socketio import SocketIO
import secrets
app = Flask(__name__, static_url_path='/static')
app.secret_key = secrets.secret_key
sock = SocketIO(app)
from cloud_app import routes
routes.py (保持不变,并且明显删除了实际逻辑)
...
from flask_cors import CORS
cors = CORS(app, resources={r"/*": {"origins": "*"}}, headers=['Content-Type'], expose_headers=['Access-Control-Allow-Origin'], supports_credentials=True)
@app.route('/example')
def example():
return 'example'
@sock.on('connect', namespace='/example')
def handle_example_connect():
sock.emit('example', 'Connected!\nAwaiting commands...\n', namespace='/example')
...
取自documentation for flask-socketio and uwsgi的翻译成ini文件
[uwsgi]
module = wsgi:app
master = true
processes = 5
buffer-size=32768
http-websockets = true
http = :8000
gevent = 1000
此处不需要nginx配置,因为webpack可以提供此服务,并且ini文件配置为直接响应http请求' http =:port '
控制台:这有时会打印它正在连接'已连接! 在 routes.py 中的 connect 事件中,正在等待命令...”,但是它还会出现以下错误
POST http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MgTjSL-&sid=5bf4758a09034805b1213fec92620e39 400 (BAD REQUEST)
GET http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MgTjSMG&sid=5bf4758a09034805b1213fec92620e39 400 (BAD REQUEST)
websocket.js:112 WebSocket connection to 'ws://localhost:8000/socket.io/?EIO=3&transport=websocket&sid=5bf4758a09034805b1213fec92620e39' failed: Error during WebSocket handshake: Unexpected response code: 400
UWSGI进程输出:
...
[pid: 9402|app: 0|req: 16/33] 127.0.0.1 () {44 vars in 1316 bytes} [Thu May 9 13:55:41 2019] POST /socket.io/?EIO=3&transport=polling&t=MgTl93y&sid=b208e874c0e64330bdde35ae1773b4e0 => generated 2 bytes in 0 msecs (HTTP/1.1 200) 3 headers in 137 bytes (3 switches on core 996)
[pid: 9402|app: 0|req: 17/34] 127.0.0.1 () {40 vars in 1255 bytes} [Thu May 9 13:55:41 2019] GET /socket.io/?EIO=3&transport=polling&t=MgTl94Q&sid=b208e874c0e64330bdde35ae1773b4e0 => generated 12 bytes in 0 msecs (HTTP/1.1 200) 3 headers in 151 bytes (3 switches on core 996)
...
[pid: 9402|app: 0|req: 27/48] 127.0.0.1 () {44 vars in 1316 bytes} [Thu May 9 13:56:57 2019] POST /socket.io/?EIO=3&transport=polling&t=MgTlRbG&sid=5c4c38f18f6b47798978440edd181512 => generated 2 bytes in 0 msecs (HTTP/1.1 200) 3 headers in 137 bytes (3 switches on core 998)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask_socketio/__init__.py", line 43, in __call__
start_response)
File "/usr/local/lib/python2.7/dist-packages/engineio/middleware.py", line 47, in __call__
return self.engineio_app.handle_request(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/socketio/server.py", line 360, in handle_request
return self.eio.handle_request(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/engineio/server.py", line 322, in handle_request
start_response(r['status'], r['headers'] + cors_headers)
IOError: headers already sent
...
取自this question。 ini文件
[uwsgi]
module = wsgi:app
master = true
processes = 5
buffer-size=32768
http-websockets = true
socket = example_app.sock
chmod-socket = 666
vaccum = true
die-on-term = true
nginx服务器
server {
listen 8000;
location /{
include uwsgi_params;
uwsgi_pass unix:/path/to/app/example_app.sock;
}
location /socket.io {
#include proxy_params;
proxy_http_version 1.1;
#proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://unix:/path/to/app/example_app.sock;
}
}
注释掉的选项以前未被注释
错误
控制台:
polling-xhr.js:263 GET http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MgTotN9 502 (Bad Gateway)
Access to XMLHttpRequest at 'http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MgTotN9' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
nginx错误日志(/ var / log / nginx / error_log)
2019/05/09 14:16:35 [error] 11338#0: *1 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: , request: "GET /socket.io/?EIO=3&transport=polling&t=MgTpw36 HTTP/1.1", upstream: "http://unix:/path/to/app/example_app.sock:/socket.io/?EIO=3&transport=polling&t=MgTpw36", host: "localhost:8000", referrer: "http://localhost:3000/home"
请注意,在两个示例中,http请求(由应用程序处理的请求)都能正常工作,只有套接字调用才会发出请求。
答案 0 :(得分:0)
flask_socketio包装应用程序,并根据可用内容和调用方式使用不同的协议。它可以同时使用HTTP轮询和本机Websocket,这是使用两种不同协议的两种不同方法。
如果仅使用 eventlet 或 gevent ,则使用轮询,即http请求。
如果使用 UWSGI ,则使用本机Websocket(ws)。
如果 gevent 或 eventlet 与 uwsgi 结合使用,则使用 uwsgi 的本机Websocket实现
在我的情况下,我在使用http轮询的客户端上使用了socket.io,因此,当我尝试使用uwsgi时,服务器期望使用本机websocket连接,并且没有任何可处理http轮询的内容。 / p>
因此,为了解决我的问题,我测试了以下解决方案