2013-04-13 18 views
7

Ho un'app Ruby on Rails 3.2 con la gemma websocket-rails, che gira su un server web sottile dietro un reverse proxy nginx.Configurazioni Thin + Nginx + Websockets | Rotaie

Fatta eccezione per il reverse proxy nginx, tutto funziona perfettamente. Rimuovendo il reverse proxy nginx, la comunicazione websocket funziona perfettamente. (sia lo sviluppo che la produzione). L'utilizzo di nginx come proxy inverso per i web socket è il punto in cui inizia il problema.

Nginx versione 1.3.13 e successive devono essere in grado di supportare il proxy Websocket. Sulla base dei documenti here e here ho creato la seguente configurazione nginx:

map $http_upgrade $connection_upgrade { 
    default upgrade; 
    ''  close; 
} 

upstream ravecy { 
    server localhost:3000; 
    server localhost:3001; 
} 

server { 
    listen 80; 
    server_name test.ravecy.com; 

    root /var/www/ravecy.com/public; 

    location/{ 
    try_files $uri @ravecy; 
    } 

    location @ravecy { 
    proxy_pass http://ravecy; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection $connection_upgrade; 
    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_redirect off; 
    } 
} 

Purtroppo, però, questo non funziona. Io non so esattamente perché, ma mi sembra che nginx non gestisce i miei websocket tentativi di connessione come i collegamenti websocket ma connessioni HTTP regolari, come si è visto dai log:

==> production.log <== 
Started GET "/chat" for 82.170.121.62 at 2013-04-10 12:20:12 +0200 
Processing by ApplicationController#chat as HTML 
    Rendered application/chat.html.erb within layouts/frontend (0.2ms) 
    Rendered layouts/frontend/_navbar.html.erb (6.3ms) 
    Rendered layouts/shared/_alert.html.erb (0.0ms) 
    Rendered layouts/frontend/_facebook_sdk.html.erb (0.0ms) 
Completed 200 OK in 9ms (Views: 8.4ms | ActiveRecord: 0.4ms) 
Started GET "/websocket" for 82.170.121.62 at 2013-04-10 12:20:12 +0200 

==> websocket_rails.log <== 
I [2013-04-10 12:20:12.744] [ConnectionManager] Connection opened: #<Connnection::47398780> 

I [2013-04-10 12:20:12.745] [Dispatcher] Started Event: client_connected 
I [2013-04-10 12:20:12.745] [Dispatcher] Name: client_connected 
I [2013-04-10 12:20:12.745] [Dispatcher] Data: {"connection_id"=>47398780} 
I [2013-04-10 12:20:12.745] [Dispatcher] Connection: #<Connnection::47398780> 

I [2013-04-10 12:20:12.747] [Dispatcher] Event client_connected Finished in 0.001960819 seconds 


==> /var/log/nginx/access.log <== 
82.170.121.62 - - [10/Apr/2013:12:20:12 +0200] "GET /chat HTTP/1.1" 200 854 "http://test.ravecy.com/posts" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" 
82.170.121.62 - - [10/Apr/2013:12:20:12 +0200] "GET /assets/frontend-6ad91089203a6026624ce015c2800492.css HTTP/1.1" 304 0 "http://test.ravecy.com/chat" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" 
82.170.121.62 - - [10/Apr/2013:12:20:12 +0200] "GET /assets/frontend-98fa493fc9f482c0d44b31bda5a89135.js HTTP/1.1" 304 0 "http://test.ravecy.com/chat" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" 

==> websocket_rails.log <== 
I [2013-04-10 12:20:12.832] [ConnectionManager] Connection closed: #<Connnection::47398780> 

I [2013-04-10 12:20:12.832] [Dispatcher] Started Event: client_disconnected 
I [2013-04-10 12:20:12.832] [Dispatcher] Name: client_disconnected 
I [2013-04-10 12:20:12.832] [Dispatcher] Data: nil 
I [2013-04-10 12:20:12.832] [Dispatcher] Connection: #<Connnection::47398780> 

I [2013-04-10 12:20:12.833] [Dispatcher] Event client_disconnected Finished in 0.000293462 seconds 


==> /var/log/nginx/access.log <== 
82.170.121.62 - - [10/Apr/2013:12:20:12 +0200] "GET /websocket HTTP/1.1" 200 398 "-" "-" 

Si noti che la connessione è chiusa entro 100 ms, anche se dovrebbe essere tenuto in vita.

Ulteriori configurazioni: nginx.conf:

user www-data; 
worker_processes 4; 
pid /run/nginx.pid; 

events { 
    worker_connections 768; 
} 

http { 
    sendfile on; 
    tcp_nopush on; 
    tcp_nodelay on; 
    keepalive_timeout 65; 
    types_hash_max_size 2048; 

    include /etc/nginx/mime.types; 
    default_type application/octet-stream; 

    access_log /var/log/nginx/access.log; 
    error_log /var/log/nginx/error.log; 

    gzip on; 
    gzip_disable "msie6"; 

    include /etc/nginx/conf.d/*.conf; 
    include /etc/nginx/sites-enabled/*; 
} 

sottile config:

--- 
chdir: /var/www/ravecy.com 
environment: production 
address: 127.0.0.1 
port: 3000 
timeout: 30 
log: log/thin.log 
pid: tmp/pids/thin.pid 
max_conns: 1024 
max_persistent_conns: 100 
require: [] 
wait: 30 
servers: 2 
daemonize: true 

versione nginx: nginx/1.3.15 url di vivere esempio: http://test.ravecy.com/chat

Nota: dopo aver eseguito new WebSocket("ws://test.ravecy.com/websocket") nella console JS, nel browser viene richiesto "Codice di risposta inaspettato: 200".

Sono abbastanza disperato per fare questo lavoro e non so più cosa dovrei fare.

Telnet risultati Nginx:

Telnet risultati diretti per il sottile:

GET /websocket HTTP/1.1 
Host: test.ravecy.com 
Connection: Upgrade 
Upgrade: WebSocket 

HTTP/1.1 101 Web Socket Protocol Handshake 
Upgrade: WebSocket 
Connection: Upgrade 
WebSocket-Origin: 
WebSocket-Location: ws://test.ravecy.com/websocket 

[["client_connected",{"id":null,"channel":null,"data":{"connection_id":37489460},"success":null,"result":null,"server_token":null}]][["users",{"id":null,"channel":null,"data":[],"success":null,"result":null,"server_token":null}]][["client_connected",{"id":null,"channel":null,"data":{},"success":false,"result":null,"server_token":null}]] 

Ovviamente, questo è erano roba va storto. Ma perché?

+0

Sembra che è fissato in http: //test.ravecy .com/chat. Qual è la causa? –

risposta

7

Sulla base dei risultati telnet ho notato che ho usato "Aggiornamento" con una "U" maiuscola. L'uso di "Aggiornamento" invece di "upgrade" ha risolto tutti i problemi che avevo ...

+0

thx! intendi nella configurazione di nginx? Dove hai cambiato esattamente la 'U'? – unludo

+1

'map $ http_upgrade $ connection_upgrade { Aggiornamento predefinito; '' vicino; } ' –

+0

grazie mille !!! mi salvi oggi il cervello omg cosa pazzesca .. nel mio caso la corretta configurazione di posizione assomiglia a questo 'proxy_http_version 1.1;' 'proxy_set_header Aggiorna $ http_upgrade;' 'proxy_set_header Connessione" Aggiornamento ";' –

0

Sì. La connessione aggiornamento sintassi per http a WS, a volte è maiuscole e minuscole

così completa configurazione del server si presenta così:

server { 
listen 80; 
server_name server.com; 

root /var/www/my-app/current/public; 

try_files $uri/index.html $uri @app; 

location @app { 
    proxy_pass http://app; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off; 
} 

# enables WS support 
location /websocket { 
    proxy_pass http://app; 
    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; 

}