2016-03-13 21 views
6

Tôi đang cố gắng chạy một ứng dụng có đường ray 5.0.0beta3 và websockets. Tôi có tất cả mọi thứ làm việc tại địa phương về phát triển nhưng trong sản xuất, tôi nhận được phản ứng này trong giao diện điều khiển của trình duyệt của tôi:Rails 5 cáp hành động SSL trong sản xuất - Kết nối WebSocket không thành công: Lỗi trong quá trình bắt tay WebSocket: Phản hồi không mong muốn 301

"Kết nối WebSocket thất bại: Lỗi trong WebSocket handshake: phản ứng bất ngờ 301"

Đây là một conf nginx tôi.

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

Tôi đang chạy mỏng cho máy chủ ứng dụng của mình và chạy puma cho máy chủ webs cùng với làm lại cục bộ. Tôi đang cố gắng làm theo ứng dụng ví dụ về cáp hành động tại đây: https://github.com/rails/actioncable-examples.

Tôi bắt đầu máy chủ của tôi puma như thế này: bundle exec puma -p 28080 cable/config.ru

Với điều này puma.rb trong config:

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" 

Dưới đây là những phần liên quan của production.rb cấu hình của tôi:

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 

Đây là cấu hình development.rb của tôi:

config.action_cable.url = "ws://localhost:28080" 
config.action_cable.allowed_request_origins = ['http://localhost:3000'] 
config.action_cable.disable_request_forgery_protection = true 

Trong ứng dụng của tôi, tôi bắt đầu cáp của tôi như thế này:

@App = {} 
App.cable = ActionCable.createConsumer() 

Mọi góp ý sẽ được awesome. Tôi đã nhận thấy ai đó ở đây: RoR 5.0.0 ActionCable wss WebSocket handshake: Unexpected response code: 301 có thể giải quyết vấn đề này bằng cách sử dụng tên miền riêng biệt. Đó là những gì tôi có thể sẽ cố gắng tiếp theo nhưng tôi đã hy vọng nó sẽ không đến đó.

Cảm ơn bạn đã giúp đỡ! Tôi rất trân trọng điều này.

Trả lời

1

Tôi không thể tìm ra vấn đề trước đó của mình vì vậy tôi đã kết thúc triển khai với hành khách thay thế. Tôi vẫn tự hỏi tại sao mọi yêu cầu đều có 301, nhưng hey, ít nhất tôi có websockets trong sản xuất ngay bây giờ!

EDIT: Sau khi đọc câu trả lời của troelskn ở trên, tôi đã có thể triển khai máy chủ Puma mà không cần Passenger.

+0

Bạn vẫn nhận được 301? –

21

Sự cố có thể là Rails đang buộc kết nối của bạn vào ssl. Vì nginx chấm dứt kết nối ssl, bạn cần đặt tiêu đề X-Forwarded-Proto để cho Rails biết tất cả đều tốt. Dưới đây là một cấu hình đầy đủ mà làm việc cho tôi:

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

Xin chào! Điều đó đã hiệu quả! Cảm ơn một tấn! Bây giờ tôi đang chạy một máy chủ Puma cho máy chủ ứng dụng và máy chủ web của tôi. Trước khi tôi đã cố gắng mỏng cho máy chủ ứng dụng của tôi và puma như máy chủ web đứng một mình máy chủ. Tôi không chắc chắn những gì offs thương mại đang ở đây, nhưng tôi chỉ khá hài lòng với nó làm việc mà không có hành khách. Cảm ơn một lần nữa! – BenNapp

+2

Điều này sẽ được đánh dấu là câu trả lời đúng! +1 – aliibrahim

+0

@BenNapp kiểm tra vấn đề này https://github.com/websocket-rails/websocket-rails/issues/151, vì puma không phải là EventMachine mà bạn phải sử dụng máy chủ rack dựa trên sự kiện hoặc chạy puma ở chế độ chờ một mình chế độ –

0

cho WebSocket-ray tôi phải làm điều này trong 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; 
    } 

và vượt qua sai trên javascript để sử dụng http: // thay vì ws : //

var websocket = new WebSocketRails(window.location.hostname + '/websocket', false); 
0

Tôi đã cập nhật câu trả lời của mình về cơ bản, điều này khá dễ dàng đối với tôi mà tôi không thể nhận ra trước đó. Tôi chỉ làm điều này trong file production.rb của tôi sau khi cấu hình SSL như cách bình thường trong file conf nginx.

config.action_cable.allowed_request_origins = [#domains] 

Nó vừa làm mọi thứ và đang kết nối đúng cách.

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