首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ActionCable -在生产中未能升级到WebSocket

ActionCable -在生产中未能升级到WebSocket
EN

Stack Overflow用户
提问于 2016-11-25 14:10:40
回答 8查看 17.8K关注 0票数 24

ActionCable在生产中不起作用。在开发中效果很好,但在生产中却不起作用。

在Ubuntu 14.04上与Puma一起运行Nginx。我已经检查过redis服务器是否已经启动和运行。

Rails -v 5.0.0.1

production.log

代码语言:javascript
运行
复制
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

客户的请求:

代码语言:javascript
运行
复制
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

响应:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
redis: &redis
  adapter: redis
  url: redis://127.0.0.1:6379

production: *redis

development:
  adapter: async

test:
  adapter: async

production.rb

代码语言:javascript
运行
复制
config.action_cable.allowed_request_origins = ["http://mityakoval.com"]

routes.rb

代码语言:javascript
运行
复制
mount ActionCable.server, at: '/cable'

更新:

不要忘记重新启动nginx :)这是我的问题所在。

EN

回答 8

Stack Overflow用户

发布于 2017-08-12 12:06:34

您应该将proxy_pass属性值从http://puma更改为http://puma/cable

因此,location的正确/cable部分是:

代码语言:javascript
运行
复制
location /cable {
  proxy_pass http://puma/cable;
  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";
}
票数 19
EN

Stack Overflow用户

发布于 2020-02-13 17:48:42

虽然其他帖子已经正确地发布了解决方案,但我想我应该发布更多的信息,说明如何识别问题所在/为其他noobs修复它。

如果rails错误包含proxy_set_header Upgrade,您将知道nginx配置在安装操作线缆的路径上需要HTTP_UPGRADE:。(意味着没有任何东西传递给HTTP_UPGRADE)。修复问题后,我的日志将显示HTTP_UPGRADE: websocket

  • Gotchya 1:正如op所提到的,请确保在进行更改后重新启动nginx (我做错了此操作)。
  • Gotchya 2:还可以在nginx配置中查找include语句,因为您的配置可能被拆分为多个文件。location /cable {部分应该在server {的内部,在我的例子中,它是缺少的,因为它位于一个与一个包含语句不同的配置文件中,我有一段时间没有注意到它。
  • 类似的错误,但不同的问题:您的rails日志将在OP提到的日志中包含一个额外的错误,即不允许原点,即当您的rails配置需要更新时,因为另一个答案提到更新config.action_cable.allowed_request_origins。

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

票数 8
EN

Stack Overflow用户

发布于 2017-06-09 21:12:55

但是,对于任何使用Rails5、Action等和来面对相同错误消息的人来说,使用设计,您只需像建议的这里那样简单地解决这个问题。这一切归结为web套接字服务器没有会话,因此出现错误消息。

app/信道/应用程序_电缆/connection.rb

代码语言:javascript
运行
复制
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable', current_user.name
    end

    protected
      def find_verified_user
        verified_user = User.find_by(id: cookies.signed['user.id'])
        if verified_user && cookies.signed['user.expires_at'] > Time.now
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

app/config/initializers/warden_hooks.rb

代码语言:javascript
运行
复制
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

解决方案是由格雷格·莫尔纳开发的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40806875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档