如何解决WebSocket 握手期间的 Rails 6 生产 ActionCable 错误
WebSocket connection to 'ws://my-ec2/cable' Failed:
Error during WebSocket handshake: Unexpected response code: 404
伙计们,我在这里经常看到这个(旧)问题,所以它看起来像是重复的。但就我而言,我非常努力地修复这个错误,但我做不到。 我也遵循此更正:https://stackoverflow.com/a/55715218/8478892 但没有成功。
我的 Nginx.conf:
upstream puma {
server unix:///home/ubuntu/apps/my_app/shared/tmp/sockets/my_app-puma.sock;
}
server {
listen 80 default_server deferred;
# If you're planning on using SSL (which you should),you can also go ahead and fill out the following server_name variable:
# server_name example.com;
# Don't forget to update these,too
root /home/ubuntu/apps/my_app/current/public;
access_log /var/log/Nginx/Nginx.access.log;
error_log /var/log/Nginx/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 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;
}
在我的 cable.yml 中:
production:
url: redis://http://my-ec2.com:6379
local: &local
url: redis://localhost:6379
development: *local
test: *local
还有我的环境/production.rb:
Rails.application.configure do
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.active_storage.service = :local
config.action_cable.mount_path = '/cable'
config.action_cable.url = 'ws://my-ec2/cable'
config.action_cable.allow_same_origin_as_host = true
config.action_cable.allowed_request_origins = ["*"]
config.log_level = :debug
config.log_tags = [ :request_id ]
config.action_mailer.perform_caching = false
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.log_formatter = ::Logger::Formatter.new
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
config.active_record.dump_schema_after_migration = false
end
为遇到此问题的人而思考的一天:
在本地主机上设置 ActionCable 已经很不错了,但在生产环境中设置则是一场完整的战争。
解决方法
你的机器上安装了redis还是docker容器?我认为您正在将它与 sidekiq 一起使用,您是否在 /config/initializers
下有任何 sidekiq/redis 初始值设定项文件?
在 cable.yml
中应该是
production:
url: redis://redis:6379/0
,
几天后,我设法自己解决了这个问题。 我的错误的主要原因是在我的环境/production.rb 文件中,我说 actioncable 端点是我的 ec2 的公共 ip。但实际上你应该把本地主机。我使用了与 development.rb 中相同的配置:
production.rb 之前:
...
config.action_cable.mount_path = '/cable'
config.action_cable.url = 'ws://my_ec2/cable'
config.action_cable.allow_same_origin_as_host = true
config.action_cable.allowed_request_origins = ["*"]
...
production.rb 之后:
...
config.action_cable.disable_request_forgery_protection = true
config.action_cable.url = "ws://localhost:3000/cable"
config.action_cable.allowed_request_origins = [/http:\/\/*/,/https:\/\/*/]
config.action_cable.allowed_request_origins = /(\.dev$)|^localhost$/
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。