11

我最近将我的 Rails 项目从 Rails4 切换到 5.0.0.beta3 以使用很棒的 ActionCable。

我的 ActionCable 服务器在 unicorn 内运行。在开发中一切正常。在生产中我有

Started GET "/cable" for xxx.xxx.xxx.xxx at 2016-03-28 18:06:38 +0300
Started GET "/cable/" [WebSocket] for xxx.xxx.xxx.xxx at 2016-03-28 18:06
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Registered connection (189772ff-6229-48f1-ae7f-d9a96ad3a6c3)
Finished "/cable/" [WebSocket] for xxx.xxx.xxx.xxx at 2016-03-28 18:06:35

并且此消息在循环中一次又一次地重复。

我在 stackoverflow 上尝试了很多选项来处理这个问题,但没有任何帮助。我的 nginx 配置:

 upstream unicorn {
   server unix:/tmp/unicorn.my_app.sock fail_timeout=0;
 }

 server {
   server_name www.my_app.com;
   return 301 $scheme://my_app.com$request_uri;
 }

 server {
   listen 80 default deferred;
   server_name my_app.com;
   root /var/www/my_app/current/public;

   location ^~ /assets/ {
     gzip_static on;
     expires max;
     add_header Cache-Control public;
   }

   try_files $uri/index.html $uri @unicorn;
   location @unicorn {
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     proxy_pass http://unicorn;
   }

   location /cable {
     proxy_pass http://unicorn/cable;
     proxy_http_version 1.1;
     proxy_set_header Upgrade websocket;
     proxy_set_header Connection Upgrade;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }

   error_page 500 502 503 504 /500.html;
   keepalive_timeout 5;
 }

为了确保允许该请求,我在初始化程序中临时使用了此代码: ActionCable.server.config.disable_request_forgery_protection = true

我的cable.coffee档案

 @App ||= {}
 App.cable = ActionCable.createConsumer "/cable"

我的config/cable.yml档案

production:
 adapter: redis
 url: redis://localhost:6379/1

我在这个问题上没有那么有经验,所以任何帮助都会很棒。

4

3 回答 3

4

location /cable节需要添加一行proxy_set_header Host $http_host;

应该:

location /cable {
     proxy_pass http://unicorn/cable;
     proxy_http_version 1.1;
     proxy_set_header Upgrade websocket;
     proxy_set_header Connection Upgrade;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
   }
于 2017-04-24T06:41:40.497 回答
3

这是我用于我的网站的配置,它似乎工作正常(Rails 5 + Nginx + Unicorn + Capistrano)。您在片段中看到的内容来自h5bp/server-configs-nginx,但我认为它们不会成为您的配置不起作用的原因。

upstream example_app {
  server unix:/home/username/www/example.com/current/tmp/sockets/unicorn.example.com.sock fail_timeout=0;
}

server {
  listen 80;
  server_name example.com www.example.com;

  return 301 https://example.com$request_uri;
}

server {
  listen 443 ssl;
  server_name www.example.com;

  include h5bp/directive-only/ssl.conf;
  ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

  return 301 https://example.com$request_uri;
}

server {
  listen 443 ssl;
  server_name example.com;

  include h5bp/directive-only/ssl.conf;
  ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

  root /home/username/www/example.com/current/public;

  # Set maximum request body size for uploads
  client_max_body_size 25m;

  try_files $uri/index.html $uri @unicorn;
  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect off;
    proxy_pass http://example_app;
  }

  location /cable {
    proxy_pass http://example_app;
    proxy_http_version 1.1;
    proxy_set_header Upgrade websocket;
    proxy_set_header Connection Upgrade;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect off;
  }

  access_log /var/log/nginx/example.com/access.log;
  error_log /var/log/nginx/example.com/error.log;

  charset utf-8;
  server_tokens off;

  error_page 404 /404.html;

  include h5bp/basic.conf;
}

电缆.yml

production:
  adapter: redis
  url: redis://localhost:6379/1

电缆.js

//= require action_cable
//= require_self
//= require_tree ./channels

(function() {
  this.App || (this.App = {});

  App.cable = ActionCable.createConsumer();

}).call(this);
于 2016-12-22T11:25:36.377 回答
1

我实施了 rack-timeout。设置正确的超时纠正了我的问题。设置这些变量的正确方法是在 config.ru 使用语句中,如下所示:

use Rack::Timeout, service_timeout: 5
于 2016-07-07T17:47:48.437 回答