我正在尝试运行与轨道5.0.0beta3和websockets的应用程序。 我有一切在本地开发工作,但在生产中我得到这个响应在我的浏览器的控制台:
“WebSocket连接失败:WebSocket握手期间出错:意外的响应301”
这是我的nginx conf。
upstream app { server unix:/home/dev/workspace/my_app/tmp/sockets/thin.0.sock max_fails=1 fail_timeout=15s; server unix:/home/dev/workspace/my_app/tmp/sockets/thin.1.sock max_fails=1 fail_timeout=15s; } server { listen 443 ssl; server_name www.my_app.co; root /home/dev/workspace/my_app/public; try_files $uri/index.html $uri @app; location @app { proxy_next_upstream error timeout http_502 http_503; proxy_read_timeout 60s; proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-FORWARDED-PROTO $scheme; proxy_redirect off; } location /websocket/ { proxy_pass http://localhost:28080/; 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; ssl on; ssl_certificate /ssl/www.my_app.co.crt; ssl_certificate_key /ssl/www.my_app.co.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; }
我正在为我的应用程序服务器运行精简版,并在本地运行websockets服务器以及redis。 我正在尝试按照这里的行动电缆示例应用程序: https : //github.com/rails/actioncable-examples 。
我开始像我这样的美洲狮服务器: bundle exec puma -p 28080 cable/config.ru
有了这个在config
puma.rb
:
workers 1 threads 1, 10 app_dir = File.expand_path("../..", __FILE__) shared_dir = "#{app_dir}/shared" rails_env = ENV['RAILS_ENV'] || "production" environment rails_env stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true pidfile "#{shared_dir}/pids/puma.pid" state_path "#{shared_dir}/pids/puma.state"
这里是我的production.rb
configuration的相关部分:
config.action_cable.allowed_request_origins = ['https://www.chatben.co', 'https://45.55.192.195'] config.action_cable.url = "wss://www.chatben.co/websocket" config.force_ssl = false
这是我的development.rb
configuration:
config.action_cable.url = "ws://localhost:28080" config.action_cable.allowed_request_origins = ['http://localhost:3000'] config.action_cable.disable_request_forgery_protection = true
在我的应用程序中,我开始这样的电缆:
@App = {} App.cable = ActionCable.createConsumer()
任何build议将是真棒。 我注意到这里有人: RoR 5.0.0 ActionCable wss WebSocket握手:意外的响应代码:301能够通过使用一个单独的域来解决这个问题。 这是我可能会尝试接下来,但我希望它不会来。
提前感谢任何帮助! 对此,我真的非常感激。
问题可能是Rails强制连接到ssl。 由于nginx终止了ssl连接,所以你需要设置X-Forwarded-Proto
头让Rails知道一切都很好。 这里有一个完整的配置适合我:
location /cable { proxy_pass http://app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_redirect off; }
我不知道我以前的问题,所以我最终与乘客部署。 我仍然想知道为什么每个请求都有一个301,但是,嘿,至少我现在正在生产websocket!
编辑:在阅读上面的troelskn的答案后,我能够部署一个彪马服务器,而不需要乘客。
对于websocket-rails我必须在NGINX中做到这一点:
location /websocket{ proxy_pass http://localhost:3001/websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_redirect off; }
并在JavaScript上传递false以使用http://而不是ws://
var websocket = new WebSocketRails(window.location.hostname + '/websocket', false);
我更新了我的答案,基本上这对我来说很容易,而我之前并不知道。 我只是在nginx conf文件中像正常的方式配置SSL之后,在我的production.rb文件中做了这个。
config.action_cable.allowed_request_origins = [#domains]
它只是做了一切,连接正确。