nginx - RoR 5.0.0 ActionCable wss WebSocket handshake: Código de respuesta inesperado: 301
puma ruby-on-rails-5 (3)
Su URI de websocket es /cable/
y no /cable
, por lo que este último golpeará la location /
bloque. Tratar:
location /cable {
rewrite ^/cable$ / break;
rewrite ^/cable(.*)$ $1 break;
proxy_pass http://websocket;
...
}
Además, no estoy seguro de que necesite un break;
ahí. Supongo que la falta }
entre los dos bloques de location
es solo un error tipográfico en la pregunta.
EDIT1: Se agregó una rewrite
para restaurar la correlación ascendente correcta.
EDIT2: La solución alternativa es reescribir explícitamente /cable
a /cable/
esta manera:
location = /cable { rewrite ^ /cable/ last; }
location /cable/ {
proxy_pass http://websocket/;
...
}
Hola. Estoy intentando servir un chat simple usando ror 5.0.0 beta (con puma) trabajando en modo de producción (en localhost no hay problemas).
Esta es mi configuración de Nginx :
upstream websocket {
server 127.0.0.1:28080;
}
server {
listen 443;
server_name mydomain;
ssl_certificate ***/server.crt;
ssl_certificate_key ***/server.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers
HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins.access.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:3000;
proxy_read_timeout 90;
proxy_redirect http://localhost:3000 https://mydomain;
location /cable/{
proxy_pass http://websocket/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
break;
}
}
Esto es config / redis / cable.yml
producción: url: redis: // localhost: 6379/1
desarrollo: url: redis: // localhost: 6379/2
prueba: url: redis: // localhost: 6379/3
y config / environments / production.rb
# Action Cable endpoint configuration
config.action_cable.url = ''wss://mydomain/cable''
# config.action_cable.allowed_request_origins = [ ''http://example.com'', /http:////example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = false
Y este es el error que estoy recibiendo:
aplicación - [...]. js: 27 Falló la conexión WebSocket a ''wss: // mydomain / cable'': Error durante el protocolo de enlace WebSocket: código de respuesta inesperado: 301
¿Algun consejo? :) Gracias
Pasé casi 5 horas ayer tratando de resolver este problema en particular. Terminé usando un dominio separado para la conexión websocket llamada ws.example.com
ya que todo lo demás dio como resultado un 301 redirect
.
Aquí está mi archivo nginx.conf
. Eliminé las partes de SSL, pero solo podría insertar las suyas. Tenga en cuenta que necesita nginx 1.4+ ya que todo lo anterior a esta versión no admite proxys de websocket.
upstream socket {
server unix:/mysocket fail_timeout=0;
}
upstream websocket {
server 127.0.0.1:28080;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'''' close;
}
server {
listen 443 ssl;
server_name ws.example.com;
access_log off;
# SSL configs here
location / {
proxy_pass http://websocket/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
server {
listen 443 ssl;
server_name example.com;
# SSL configs here
location @app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://socket;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Leí en alguna parte que allowed_request_origins
no funcionó como se esperaba, así que fui de forma segura (hasta que se solucione el error) y ActionCable.server.config.disable_request_forgery_protection = true
completo el comprobador con ActionCable.server.config.disable_request_forgery_protection = true
.
Aquí está mi archivo cable.ru
para iniciar el cable de acción.
require ::File.expand_path(''../../config/environment'', __FILE__)
Rails.application.eager_load!
require ''action_cable/process/logging''
Rails.logger.level = 0
ActionCable.server.config.disable_request_forgery_protection = true
run ActionCable.server
También estoy usando la última versión de Rails de Github.
gem "rails", github: "rails/rails"
Resolví agregar pasajeros de Fusion.
nginx config ahora es:
server{
listen 80;
passenger_enabled on;
passenger_app_env production;
passenger_ruby /../ruby-2.3.0/ruby;
root /path to application/public;
client_max_body_size 4G;
keepalive_timeout 10;
[...]
location /cable{
passenger_app_group_name websocket;
passenger_force_max_concurrent_requests_per_process 0;
}
}
Debe eliminar la configuración de carpeta predeterminada / redis / cable.yml y mover ese archivo a / config solamente.
Para SSL simplemente habilite las opciones de ssl predeterminadas y funcionará .-)
Gracias a todos por la ayuda