2013-04-13 34 views
7

Tôi có ứng dụng Ruby on Rails 3.2 với đá quý websocket-ray, chạy trong một máy chủ web mỏng phía sau proxy ngược nginx.Cấu hình Thin + Nginx + Websockets | Rails

Ngoại trừ proxy ngược nginx, mọi thứ hoạt động tốt. Bằng cách loại bỏ proxy ngược nginx, giao tiếp websocket hoạt động tốt. (cả phát triển và sản xuất). Sử dụng nginx như một proxy ngược cho các websockets là nơi mà vấn đề bắt đầu.

Nginx phiên bản 1.3.13 trở lên sẽ có thể hỗ trợ proxy websocket. Dựa trên các tài liệu herehere tôi tạo ra các cấu hình nginx sau:

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

Đáng buồn thay, tuy nhiên, điều này không làm việc. Tôi không biết chính xác lý do tại sao, nhưng có vẻ như với tôi rằng nginx không xử lý cố gắng kết nối WebSocket của tôi là kết nối WebSocket nhưng các kết nối HTTP thông thường, khi nhìn từ các bản ghi:

==> 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 "-" "-" 

Lưu ý rằng kết nối đã bị đóng trong 100ms, mặc dù nó phải được giữ sống.

configs thêm: 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/*; 
} 

mỏng cấu hình:

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

phiên bản nginx: nginx/1.3.15 url sống Ví dụ: http://test.ravecy.com/chat

Cũng lưu ý: khi thực hiện new WebSocket("ws://test.ravecy.com/websocket") trong bảng điều khiển JS, trình duyệt sẽ nhắc "Mã phản hồi không mong muốn: 200".

Tôi khá tuyệt vọng để thực hiện công việc này và không còn biết tôi nên làm gì nữa.

quả Telnet nginx:

Telnet kết quả trực tiếp đến mỏng:

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

Rõ ràng, đây là những thứ đi sai. Nhưng tại sao?

+0

Có vẻ nó cố định trong http: //test.ravecy .com/chat. Nguyên nhân là gì? –

Trả lời

7

Dựa trên kết quả telnet tôi lưu ý rằng tôi đã sử dụng "Nâng cấp" với số vốn "U". Sử dụng "Nâng cấp" thay vì "nâng cấp" đã khắc phục tất cả các sự cố mà tôi đã gặp phải ...

+0

thx! bạn có nghĩa là trong cấu hình nginx? Bạn đã thay đổi chính xác 'U' ở đâu? – unludo

+1

'map $ http_upgrade $ connection_upgrade { Nâng cấp mặc định; '' đóng; } ' –

+0

cảm ơn bạn rất nhiều !!! bạn tiết kiệm bộ não của tôi ngày hôm nay. omg những gì một công cụ điên .. trong trường hợp của tôi cấu hình đúng vị trí trông như thế này 'proxy_http_version 1.1;' 'proxy_set_header Nâng cấp $ http_upgrade;' 'proxy_set_header Kết nối" Nâng cấp "; –

0

Vâng. nâng cấp kết nối cú pháp cho http để ws vào những thời điểm là case-sensitive

Vì vậy, hoàn chỉnh cấu hình máy chủ trông như thế này:

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; 

}

Các vấn đề liên quan