ActionCable - Failed to upgrade to WebSocket in production

旧巷老猫 提交于 2019-11-30 17:21:12
Tsutomu

You should change the value of proxy_pass property from http://puma to http://puma/cable.

Therefore, the correct location section for the /cable will be:

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";
}

Super late to this conversation, however, for anyone who is facing the same error message using Rails5, Action Cable, etc. & DEVISE you simply solve it like suggested here. It all comes down to the web socket server not having a session, hence the error message.

app/channels/application_cable/connection.rb

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

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

Solution was developed by Greg Molnar

The resolution that needs a NGINX configuration changes to accept this action cable request.

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

Add the above lines to your location block in the nginx site configuration, then restart nginx.

You can change you nginx config about /cable

proxy_set_header X-Forwarded-Proto http;

I used you nginx config and add this change on myu server, it works fine.

My solution was to add these lines to my production.rb file:

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

Worked with:

location ^~ /cable {
  ...
}

Location requires ^~

Your cable.yml file should look like this:

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

Then you should have this key set up in the environment, should look something like this:

REDIS_URL: 'redis://redistogo:keyblahblahblhblah'

Also, you should have this in production.rb:

config.web_socket_server_url = "wss://YOUR_URL.com/cable"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!