Nam*_*mey 5 sockets nginx flask socket.io gevent-socketio
我在使用Python Flask-socketio库(基于gevent)很好地使用Nginx时遇到了一些麻烦.目前,由于我们正在积极开发,我试图让Nginx作为代理工作.对于发送页面,我可以通过直接运行flask-socketio app或者通过gunicorn来实现这一点.一个问题:websocket消息传递似乎不起作用.页面已成功托管和显示.但是,当我尝试使用websockets时,它们不起作用.它们还活着,websocket认为它已连接,但它们不会发送消息.如果我删除Nginx代理,它们确实有效.我尝试发送消息时Firefox给出了这个错误:
Firefox无法在ws:///socket.io/1/websocket/上建立与服务器的连接.
Web地址是服务器所在的位置,唯一ID只是一堆随机数字.它似乎足以保持连接的生效(例如,客户端认为它已连接),但不能通过websocket发送消息.我不得不认为这个问题与代理的某些部分有关,但是在调试问题时遇到了麻烦(部分原因是这是我第一次使用Flask-socketIO和nginx).我用于nginx的配置文件是:
user <user name>; ## This is set to the user name for the remote SSH session
worker_processes 5;
events {
worker_connections 1024; ## Default: 1024
}
http {
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
server {
listen 80;
server_name _;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将配置文件作为一个通用示例的混合和特定于websocket的混合,但是试图摆弄它并没有解决问题.另外,当我在wsgi模式下使用它时,我在我的Flask app.wsgi_app上使用werkzeug Proxy_Fix调用.然而,无论如何,我都试过它,但无济于事.如果有人有一些见解,我会全神贯注.
Nam*_*mey 12
我设法解决了这个问题.这些问题并非特定于烧瓶,但它们特定于Ubuntu,NginX和gevent-socketio.存在两个重要问题:
如果尝试在此配置中调试websockets,我建议执行以下步骤:
刚刚检查了所有这些东西,有一些外卖.
在Ubuntu上升级到最新的稳定nginx版本(完整参考)可以通过以下方式完成:
sudo apt-get install python-software-properties
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:nginx/stable
sudo apt-get update
sudo apt-get install nginx
Run Code Online (Sandbox Code Playgroud)
在像Windows这样的系统中,您可以使用安装程序,并且不太可能获得错误的版本.
许多配置文件可能会令人困惑,因为nginx在2013年左右正式添加套接字,使早期的解决方案配置过时.现有的配置文件并不倾向于覆盖nginx,gevent-socketio和SSL的所有基础,而是将它们全部分开(Nginx Tutorial,Gevent-socketio,Node.js with SSL).带有flask-socketio(包装gevent-socketio)和SSL的nginx 1.6的配置文件是:
user <user account, probably optional>;
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
# tcp_nopush on;
keepalive_timeout 3;
# tcp_nodelay on;
# gzip on;
client_max_body_size 20m;
index index.html;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
# Listen on 80 and 443
listen 80 default;
listen 443 ssl; (only needed if you want SSL/HTTPS)
server_name <your server name here, optional unless you use SSL>;
# SSL Certificate (only needed if you want SSL/HTTPS)
ssl_certificate <file location for your unified .crt file>;
ssl_certificate_key <file location for your .key file>;
# Optional: Redirect all non-SSL traffic to SSL. (if you want ONLY SSL/HTTPS)
# if ($ssl_protocol = "") {
# rewrite ^ https://$host$request_uri? permanent;
# }
# Split off basic traffic to backends
location / {
proxy_pass http://localhost:8081; # 127.0.0.1 is preferred, actually.
proxy_redirect off;
}
location /socket.io {
proxy_pass http://127.0.0.1:8081/socket.io; # 127.0.0.1 is preferred, actually.
proxy_redirect off;
proxy_buffering off; # Optional
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
Run Code Online (Sandbox Code Playgroud)检查Flask-socketio是否使用正确的端口很容易.这足以与上述一起使用:
from flask import Flask, render_template, session, request, abort
import flask.ext.socketio
FLASK_CORE_APP = Flask(__name__)
FLASK_CORE_APP.config['SECRET_KEY'] = '12345' # Luggage combination
SOCKET_IO_CORE = flask.ext.socketio.SocketIO(FLASK_CORE_APP)
@FLASK_CORE_APP.route('/')
def index():
return render_template('index.html')
@SOCKET_IO_CORE.on('message')
def receive_message(message):
return "Echo: %s"%(message,)
SOCKET_IO_CORE.run(FLASK_CORE_APP, host=127.0.0.1, port=8081)
Run Code Online (Sandbox Code Playgroud)对于像socketio.js这样的客户端,连接应该很容易.例如:
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
<script type="text/javascript">
var url = window.location.protocol + document.domain + ':' + location.port,
socket = io.connect(url);
socket.on('message', alert);
io.emit("message", "Test")
</script>
Run Code Online (Sandbox Code Playgroud)打开端口实际上更多的是服务器故障或超级用户问题,因为它将在很大程度上取决于您的防火墙.对于Amazon EC2,请参阅此处.
如果尝试所有这些都不起作用,请哭泣.然后返回列表顶部.因为您可能只是偶然重新安装了旧版本的nginx.