ActionCable - 无法在生产中升级到WebSocket

时间:2016-11-25 14:10:40

标签: ruby-on-rails ruby nginx ruby-on-rails-5 actioncable

ActionCable无法在生产中使用。适用于开发,但不适用于生产。

在Ubuntu 14.04上使用Puma运行Nginx。我已经检查过redis-server已启动并正在运行。

Rails -v 5.0.0.1

production.log

INFO -- : Started GET "/cable/"[non-WebSocket] for 178.213.184.193 at 2016-11-25 14:55:39 +0100
ERROR -- : Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
INFO -- : Finished "/cable/"[non-WebSocket] for 178.213.184.193 at 2016-11-25 14:55:39 +0100

来自客户的请求:

GET ws://mityakoval.com/cable HTTP/1.1
Host: mityakoval.com
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://mityakoval.com
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4,uk;q=0.2,nb;q=0.2
Cookie: _vaktdagboka_session=******
Sec-WebSocket-Key: *******
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: actioncable-v1-json, actioncable-unsupported

回应:

HTTP/1.1 404 Not Found
Server: nginx/1.4.6 (Ubuntu)
Date: Fri, 25 Nov 2016 13:52:21 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
X-Request-Id: d6374238-69ef-476e-8fc5-e2f8bbb663de
X-Runtime: 0.002500

nginx.conf

upstream puma {
  server unix:///home/mityakoval/apps/vaktdagboka/shared/tmp/sockets/vaktdagboka-puma.sock;
}

server {
  listen 80 default_server deferred;
  # server_name example.com;

  root /home/mityakoval/apps/vaktdagboka/current/public;
  access_log /home/mityakoval/apps/vaktdagboka/current/log/nginx.access.log;
  error_log /home/mityakoval/apps/vaktdagboka/current/log/nginx.error.log info;

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

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;
  }

  location /cable {
    proxy_pass http://puma;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}

cable.yml

redis: &redis
  adapter: redis
  url: redis://127.0.0.1:6379

production: *redis

development:
  adapter: async

test:
  adapter: async
production.rb中的

config.action_cable.allowed_request_origins = ["http://mityakoval.com"]
routes.rb中的

mount ActionCable.server, at: '/cable'

更新

不要忘记重新启动nginx :)这对我来说是个问题。

7 个答案:

答案 0 :(得分:5)

虽然其他帖子正确地发布了解决方案,但我想我会发布更多有关如何确定问题出在哪里/为其他nginx专家解决此问题的信息。

如果滑轨错误包含proxy_set_header Upgrade,您将知道nginx配置在您安装动作电缆的路径上需要HTTP_UPGRADE:。 (这意味着没有任何内容传递给HTTP_UPGRADE)。解决问题后,我的日志显示HTTP_UPGRADE: websocket

  • Gotchya 1:正如操作员所提到的,请确保在进行更改后重新启动nginx(我这样做是错误的)。

  • Gotchya 2:还要在nginx配置中查找include语句,因为您的配置可能会拆分为多个文件。 location /cable {部分应该位于server {的内部,在我的情况下,该部分丢失了,因为它位于与include语句不同的配置文件中,而我并没有注意到它。

  • 类似的错误,但问题不同:您的rails日志将在日志中包含一个额外的错误,就在OP提到不允许原点的操作之前,即您的rails配置需要更新为另一个答案时提到更新config.action_cable.allowed_request_origins。

日志记录可能会随着rails的变化而变化,但希望这有助于弄清问题所在,以及我对nginx一无所知的人遇到的一些问题。

答案 1 :(得分:3)

然而,对于使用Rails5,Action Cable等面临相同错误消息的任何人来说,这个对话的时间已经很晚了。 DEVISE 您只需像建议的here一样解决它。这一切都归结为没有会话的Web套接字服务器,因此出现错误消息。

的应用程序/信道/ application_cable / connection.rb

Warden::Manager.after_set_user do |user,auth,opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = user.id
  auth.cookies.signed["#{scope}.expires_at"] = 30.minutes.from_now
end
Warden::Manager.before_logout do |user, auth, opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = nil
  auth.cookies.signed["#{scope}.expires_at"] = nil
end

的应用程序/配置/初始化/ warden_hooks.rb

label1 | label2 | value

解决方案由Greg Molnar开发

答案 2 :(得分:1)

需要NGINX配置更改为接受此操作电缆请求的分辨率

location / {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

将以上行添加到nginx站点配置中的位置块,然后重新启动nginx。

答案 3 :(得分:0)

您可以更改关于/cable

的nginx配置

proxy_set_header X-Forwarded-Proto http;

我使用了你的nginx配置并在myu服务器上添加了这个更改,它运行正常。

答案 4 :(得分:0)

我的解决方案是将这些行添加到我的production.rb文件中:

  config.action_cable.url = 'ws://your_site.com/your_action_cable'
  config.action_cable.allowed_request_origins = [ 'http://your_site.com' ]

答案 5 :(得分:0)

使用:

location ^~ /cable {
  ...
}

位置需要^~

答案 6 :(得分:-1)

您的cable.yml文件应如下所示:

production:
    adapter: redis
    url: <%=ENV['REDIS_URL']%>

然后你应该在环境中设置这个键,看起来应该是这样的:

REDIS_URL: 'redis://redistogo:keyblahblahblhblah'

另外,你应该在production.rb中使用它:

config.web_socket_server_url = "wss://YOUR_URL.com/cable"