我正在尝试使用ActionCable(主要是复制DHH example)并尝试让它在具有瘦(在端口8443上)和nginx的Ubuntu服务器上运行。一切都在本地工作正常但是,当我尝试在实时服务器上代理它时,我收到此错误响应:failed: Error during WebSocket handshake: Unexpected response code: 301
。
这是我的nginx配置的相关部分:
server {
listen 80;
server_name _not_;
root /home/ubuntu/www/;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8443;
}
server {
listen 80;
...
location /websocket/ {
proxy_pass http://127.0.0.1:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
}
...
}
我在这里与nginx联盟有点 - 我错过了什么或者出错了?
答案 0 :(得分:1)
我在一个月后回到这里,发现问题不在于nginx配置,而是与瘦身有关。我做了三件事:
(1)配置精简以使用the Faye adapter:
# config.ru
require 'faye'
Faye::WebSocket.load_adapter('thin')
require ::File.expand_path('../config/environment', __FILE__)
use Faye::RackAdapter, mount: '/faye', timeout: 25
run Rails.application
(2)切换到在routes.rb
中挂载ActionCable,而不是尝试运行它as a standalone。
#routes.rb
MyAwesomeApp::Application.routes.draw do
...
match "/websocket", to: ActionCable.server, via: [:get, :post]
end
(3)返回到我的正常nginx配置,上游瘦的websockets(如网络服务器那样:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close; }
upstream thin {
server 127.0.0.1:3000;
}
server {
...
location /websocket {
proxy_pass http://thin;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; }
...
}
所以,我道歉nginx,我为你赦免 - 似乎问题主要与瘦身有关。
编辑:我添加了在路由中安装后返回的旧nginx配置。另外值得注意的是,对于那些使用SSL的人来说,config.force_ssl
会破坏安全的wss
websocket。相反,您应该在控制器级别as recommended here上执行force_ssl
,并配置nginx以重写任何到HTTPS的HTTP路由。
答案 1 :(得分:1)
这个帖子对我很有帮助,但我选择将AC进程分成一个单独的puma实例,这样我就可以单独配置worker等。我后来从nginx添加了SSL代理,以确保使用最新的密码等。这避免了rails / puma / AC不必担心SSL与非SSL的关系;服务器实例中的所有内容都是非SSL的。
这是AC的服务器部分:
x = read_port();
y = read_port();
if( x == y )
return x;
for(;;) {
z = read_port();
if( z == x || z == y )
return z;
x = y;
y = z;
}
请注意此github issue:您需要确保您的AC配置允许您的域名作为来源:
server {
listen 881 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
server_name localhost;
location / {
proxy_pass http://cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}