3

我正在尝试使用 ActionCable(主要是复制DHH 示例)并试图让它在具有瘦(在端口 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 有点格格不入——我错过了什么或出错了?

4

2 回答 2

1

一个月后我回到这个问题,发现问题不在于 nginx 配置,而与瘦有关。我做了三件事:

(1) 配置thin使用Faye适配器

# 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) 切换到在 中安装 ActionCable routes.rb,而不是尝试将其作为独立的.

#routes.rb

MyAwesomeApp::Application.routes.draw do

  ...

  match "/websocket", to: ActionCable.server, via: [:get, :post]

end

(3) 回到我正常的 nginx 配置,websockets 上游瘦(就像 webserver 一样:

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会破坏安全的wsswebsocket。相反,您应该按照此处的建议在force_ssl控制器级别进行操作,并配置 nginx 以将任何 HTTP 路由重写为 HTTPS。

于 2015-11-20T14:28:08.193 回答
1

这个线程对我很有帮助,但我选择将 AC 进程分离到一个单独的 puma 实例中,这样我就可以单独配置工作程序等。后来我从 nginx 添加了 SSL 代理,以确保使用最新的密码等。这避免了 rails/puma/AC 不得不担心 SSL 与非 SSL;服务器实例内的一切都是非 SSL 的。

这是我的 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";
    }
}

来自此 github问题的注意事项:您需要确保您的 AC 配置允许您的域作为源:

#config/initializers/cable.rb
ActionCable.server.config.allowed_request_origins = %w( http://my-domain.com  )
于 2015-12-10T14:31:11.907 回答