Ruby on rails ActionCable-WebSocket握手期间出错:意外响应代码:404

Ruby on rails ActionCable-WebSocket握手期间出错:意外响应代码:404,ruby-on-rails,nginx,actioncable,Ruby On Rails,Nginx,Actioncable,已经通过Capistrano部署了我的Rails 5.2应用程序,我在ActionCable上遇到了问题。我正在使用Nginx、Puma和Lets加密 我尝试了许多配置组合,但每次都收到相同的错误。我不知道如何调试这个问题,建议以及任何关于重新安排我的ngnx.conf的提示都将不胜感激 已将真实网站更改为website.com nginx.conf upstream puma { server unix:///home/deploy/apps/website/shared/tmp/sock

已经通过Capistrano部署了我的Rails 5.2应用程序,我在ActionCable上遇到了问题。我正在使用Nginx、Puma和Lets加密

我尝试了许多配置组合,但每次都收到相同的错误。我不知道如何调试这个问题,建议以及任何关于重新安排我的ngnx.conf的提示都将不胜感激

已将真实网站更改为website.com

nginx.conf

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

server {
  server_name website.com www.website.com;
  root /home/deploy/apps/website/current/public;
  index index.html;

  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 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;
  client_max_body_size 10M;
  keepalive_timeout 10;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.website.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = website.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

  server_name website.com www.website.com;
    return 404; # managed by Certbot
}

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


  server {
    if ($host = www.immersive.ch) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = immersive.ch) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name immersive.ch www.immersive.ch;
    return 404; # managed by Certbot
  }

  server {
    server_name immersive.ch www.immersive.ch;
    root /home/deploy/apps/immersive/current/public;
    index index.html;

    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 Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass_request_headers on;

      proxy_buffering off;
      proxy_redirect off;
      break;
    }

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

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/immersive.ch/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/immersive.ch/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }

config/production.rb

  config.action_cable.mount_path = '/cable'
  config.action_cable.url = 'wss://website.com/cable'
  config.action_cable.allowed_request_origins = [ 'https://website.com', 'http://website.com' ]

错误消息

审查员额

更新

更新nginx.conf

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

server {
  server_name website.com www.website.com;
  root /home/deploy/apps/website/current/public;
  index index.html;

  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 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;
  client_max_body_size 10M;
  keepalive_timeout 10;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.website.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = website.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

  server_name website.com www.website.com;
    return 404; # managed by Certbot
}

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


  server {
    if ($host = www.immersive.ch) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = immersive.ch) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name immersive.ch www.immersive.ch;
    return 404; # managed by Certbot
  }

  server {
    server_name immersive.ch www.immersive.ch;
    root /home/deploy/apps/immersive/current/public;
    index index.html;

    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 Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass_request_headers on;

      proxy_buffering off;
      proxy_redirect off;
      break;
    }

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

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/immersive.ch/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/immersive.ch/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }

production.rb

config.action\u cable.mount\u path='/cable'
config.action\u cable.url='1wss://immersive.ch/cable'
config.action\u cable.allow\u same\u origin\u as\u host=true
config.action\u cable.allowed\u request\u origins=['*']
#config.action\u cable.allowed\u request\u origins=['https://immersive.ch', 'http://immersive.ch' ]
旋度的部分输出

> GET /cable HTTP/1.1
> Host: immersive.ch
> User-Agent: curl/7.54.0
> Accept: */*
> Origin: https://immersive.ch
> Sec-WebSocket-Key: MIN4DsiwEAutsE11kgG5rg==
> Upgrade: websocket
> Connection: Upgrade
> Sec-WebSocket-Version: 13
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.15.5 (Ubuntu)
< Date: Tue, 16 Apr 2019 20:10:43 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache
< X-Request-Id: 7a9aa8f1-676d-419b-9e4f-0c1bb38bcaa2
< X-Runtime: 0.004730
<
* Connection #0 to host immersive.ch left intact
Page not found%
编辑2

/var/logs/nginx/access.log

HTTP/1.1" 200 4447 "https://immersive.ch/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:58 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:59 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"

2019-04-16 20:58: HTTP parse error, malformed request (127.0.0.1): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
puma.error.log

I, [2019-04-16T22:39:06.100106 #21136]  INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Started GET "/cable" for xxx.xxx.xxx.xxx at 2019-04-16 22:39:06 +0200
I, [2019-04-16T22:39:06.103811 #21136]  INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Started GET "/cable/"[non-WebSocket] for xxx.xxx.xxx.xxx at 2019-04-16 22:39
E, [2019-04-16T22:39:06.103943 #21136] ERROR -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
I, [2019-04-16T22:39:06.104062 #21136]  INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Finished "/cable/"[non-WebSocket] for xxx.xxx.xxx.xxx at 2019-04-16 22:39
puma.access.log

HTTP/1.1" 200 4447 "https://immersive.ch/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:58 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:59 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"

2019-04-16 20:58: HTTP parse error, malformed request (127.0.0.1): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
2019-04-16 20:58:HTTP解析错误,请求格式错误(127.0.0.1):#

ActionCable在
Origin
标题缺失或不匹配/无效时回答404

检查它是否不是你的常规404:

curl -v 'https://your_site.com/cable' -H 'Origin: https://your_site.com' -H 'Sec-WebSocket-Key: MIN4DsiwEAutsE11kgG5rg=='  -H 'Upgrade: websocket' -H 'Connection: Upgrade' -H 'Sec-WebSocket-Version: 13'
当一切正常时,将出现
HTTP/1.1 101交换协议
,在原点不匹配-只是
页面未找到
正文,或者如果存在其他路由问题,则会出现常规404页面

确保设置中的
允许的\u请求\u来源
正确。注意,如果它是非标准的,那么它包括端口。检查浏览器在devtools中发送的源文件

还有
config.action\u cable.allow\u same\u origin\u as\u host=true
(默认情况下,需要正确的
host
X-Forwarded-Proto
标题)

然后,我们需要nginx传递用于重建原点的所有标头:

位置/电缆{
代理通行证http://puma;
proxy_http_版本1.1;
代理设置头升级$http\U升级;
代理设置\u头连接“升级”;
代理设置头主机$Host;

proxy_set_header X-Forwarded-Proto$scheme;#回答太棒了。
Sec WebSocket Key
是什么意思?值从哪里来?@ardochigh这是WebSocket协议握手的一部分,浏览器会为每个请求生成它,以证明连接确实是WebSocket感谢伟大的答案,但仍然不走运。我会发布完整的内容nginx inc.实际的站点名称和curl.PS的输出,这些哈苏是很棒的摄像头,尤其是6x6方面。我使用Capistrano进行部署…它不会重新启动nginx。在
sudo服务nginx重新启动后,所有功能现在都可以正常工作了
谢谢@Vasfed