ruby-on-rails - 操作线无法连接(无法升级到WebSocket)

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

我在使用这些日志消息在非开发环境中连接到 websocket 时遇到问题

Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )

Finished "/cable/"[non-WebSocket] for 127.0.0.1 at 2016-07-06 09:44:29 +1000

我调试了一下,发现浏览器/javascript发送的请求与unicorn(使用nginx运行)收到的请求并不完全相同。

浏览器的请求头是

GET ws://cc-uat.com.au/cable HTTP/1.1
Host: cc-uat.com.au
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://cc-uat.com.au
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: <Lot of cookies>
Sec-WebSocket-Key: QGdJkYIA2u7vtmMVXfHKtQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: actioncable-v1-json, actioncable-unsupported

这里的连接是“升级”,但 websocket 请求的连接“已关闭”(可能 nginx 搞砸了?)

Websocket 驱动程序中的这段代码失败了

def self.websocket?(env)
      connection = env['HTTP_CONNECTION'] || ''
      upgrade    = env['HTTP_UPGRADE']    || ''

      env['REQUEST_METHOD'] == 'GET' and
      connection.downcase.split(/ *, */).include?('upgrade') and
      upgrade.downcase == 'websocket'
end

更新

这是我的 nginx 配置

upstream app {
    server unix:/home/osboxes/sites/actioncable-examples/shared/sockets/unicorn.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    root /home/osboxes/sites/actioncable-example/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_http_version 1.1;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "upgrade";
    }


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

我已在/cable 上安装了 actioncable 服务器

mount ActionCable.server => "/cable"

通过 nginx 的更改,我能够成功进行握手,但服务器无法发送心跳并且连接不断断开。

Started GET "/cable" for 127.0.0.1 at 2016-07-07 05:48:06 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2016-07-07 05:48:06 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)

最佳答案

您是否已在 production.rb 中设置 config.action_cable.allowed_request_origins 以允许来自生产域的连接? 在我的 nginx.conf 中还有

proxy_set_header X-Real-IP $remote_addr;  
proxy_set_header X-Forwarded-Proto http;

我不完全确定它们是否真的需要,但它对我有用。

关于ruby-on-rails - 操作线无法连接(无法升级到WebSocket),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38214564/

相关文章:

postgresql - 使用 Rails、Postgres 和 Sidekiq 导入 CSV

ruby-on-rails - 我应该如何检查Gravatar是否存在?

ruby-on-rails - 在 ActiveRecord 中设置数据之前,如何使 setter 方法加密数据?

c# - 如何启用 nginx 反向代理以在 .Net 核心中与 gRPC 一起使用?

node.js - 需要帮助修复我的 nginx 服务器

mysql - Ruby on Rails 和查询(理解问题)

Mysql2::错误:表中不存在键列 'hotel_user_id'

ruby-on-rails - 使用 Activeadmin + Paperclip Rails 直接上传到 Amazon S3

python - Nginx:Linux 服务器上的内部端口转发

docker - 在docker-compose上为sql:的db:和db_backup的最佳图像是什么?