2016-01-27 11 views
6

Ciao Sto cercando di servire una semplice chat usando ror 5.0.0 beta (con puma) lavorando sulla modalità di produzione (in localhost non ci sono problemi) .RoR 5.0.0 ActionCable wss Handshake WebSocket: codice di risposta inatteso: 301

Questo è il mio Nginx configurazione:

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

    } 

Questo è config/Redis/cable.yml

produzione: url: Redis: // localhost: 6379/1

sviluppo: url: redis: // localhost: 6379/2

prova: url: Redis: // localhost: 6379/3

e config/ambienti/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 

E questo è l'errore che sto ricevendo:

application - [...]. Js: 27 Connessione WebSocket a "wss: // mydomain/cable" non riuscita: errore durante l'handshake WebSocket: codice di risposta inatteso: 301

Qualche consiglio? :) Grazie

risposta

2

I risolto aggiungendo Phusion passeggero.

nginx config è ora:

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

Devi rimuovere cartella di default config/Redis/cable.yml e spostare il file a/config solo.

Per SSL solo abilitare le opzioni predefinite SSL e sarà opere .-)

Grazie a tutti per l'aiuto

0

L'URI WebSocket è /cable/ e non /cable, quindi quest'ultimo colpirà il blocco location /. Prova:

location /cable { 
    rewrite ^/cable$/break; 
    rewrite ^/cable(.*)$ $1 break; 
    proxy_pass   http://websocket; 
    ... 
} 

Inoltre, non so è necessario un break; in là. Presumo che il } mancante tra i due blocchi location sia solo un errore di battitura nella domanda.

MODIFICA 1: Aggiunto rewrite per ripristinare la mappatura upstream corretta.

EDIT2: Alternativa soluzione è quella di riscrivere esplicitamente /cable a /cable/ in questo modo:

location = /cable { rewrite^/cable/ last; } 
location /cable/ { 
    proxy_pass http://websocket/; 
    ... 
} 
+0

che cambiano posizione/via cavo/{...} per me tornare/cavo "di connessione WebSocket a ' wss: // mydomain/cable 'fallito: errore durante l'handshake WebSocket: codice di risposta inatteso: 502 " –

+0

Bad gateway: assicurati di avere il servizio in esecuzione sulla porta 28080 –

+0

Il firewall stava bloccando quella porta, ora ho cambiato redis su 4443 e "upstream websocket" {127.0.0.1:4443} -> Errore durante l'handshake WebSocket: codice di risposta imprevisto: 404 Almeno il mio codice di errore sta cambiando xd –

0

spendo quasi 5 ore di ieri cercando di risolvere questo particolare problema. Ho finito per utilizzare un dominio separato per la connessione web socket denominata ws.example.com poiché tutto il resto ha generato un 301 redirect.

Ecco il mio file nginx.conf. Ho rimosso le parti SSL, ma potresti semplicemente inserire le tue. Nota che hai bisogno di nginx 1.4+ poiché tutto ciò che precede questa versione non supporta il proxy 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; 
} 

ho letto da qualche parte che allowed_request_origins non ha funzionato come previsto così sono andato il modo sicuro (fino a quando è fissato il bug) e trasformato il correttore di completamente con ActionCable.server.config.disable_request_forgery_protection = true.

Ecco il file cable.ru per l'avvio del cavo di azione.

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 

Sto anche utilizzando la versione più recente di Rails da Github.

gem "rails", github: "rails/rails" 
Problemi correlati