2016-01-27 42 views
6

Witam Próbuję obsłużyć prosty czat przy użyciu wersji 5.0.0 beta (z pumą) pracującej w trybie produkcyjnym (w localhost nie ma problemów) .RoR 5.0.0 ActionCable wss Uzgadnianie WebSocket: Nieoczekiwany kod odpowiedzi: 301

To mój Nginx konfiguracja:

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

    } 

To config/Redis/cable.yml

produkcja: url: Redis: // localhost: 6379/1

wywołanie: adres URL: redis: // localhost: 6379/2

testy: URL: Redis: // localhost: 6379/3

i config/Środowiska/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 

i to jest błąd Otrzymuję:

Aplikacja

- [...]. Js: 27 Połączenie WebSocket z "wss: // mydomain/cable" nie powiodło się: Błąd podczas uzgadniania WebSocket: nieoczekiwany kod odpowiedzi: 301

Jakieś wskazówki? :) Dzięki

Odpowiedz

2

I rozwiązany dodanie Phusion pasażera.

nginx config jest teraz:

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

Trzeba usunąć domyślny folder config/Redis/cable.yml i przenieść ten plik do/config tylko.

Dla SSL tylko włączyć opcje ssl domyślnych i będzie prace .-)

Dzięki wszystkim za pomoc

0

Twój identyfikator URI Websocket to /cable/, a nie /cable, więc ten ostatni trafi w blok location /. Wypróbuj:

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

Ponadto, nie wiesz, czy potrzebujesz tam break;. Przypuszczam, że brakujący } między dwoma blokami location jest po prostu literówką w pytaniu.

EDYCJA1: Dodano rewrite, aby przywrócić prawidłowe odwzorowanie upstream.

EDIT2: Alternatywne rozwiązanie jest wyraźnie przepisać /cable do /cable/ tak:

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

zmieniających położenie/kabel/{...} do/kablowa powrócić mnie „Połączenie websocket do ' wss: // mydomain/cable 'failed: Błąd podczas uzgadniania WebSocket: Nieoczekiwany kod odpowiedzi: 502 " –

+0

Zła brama - upewnij się, że masz uruchomioną usługę na porcie 28080 –

+0

Zapora blokowała ten port, teraz zmieniłem tryb Redis na 4443 i "upstream websocket" {127.0.0.1:4443} -> Błąd podczas uzgadniania WebSocket: Nieoczekiwany kod odpowiedzi: 404 Co najmniej mój kod błędu zmienia się xd –

0

spędzam prawie 5 godzin wczoraj próbuje rozwiązać ten konkretny problem. Skończyło się na użyciu osobnej domeny dla połączenia websocket o nazwie ws.example.com, ponieważ wszystko inne zaowocowało 301 redirect.

Oto mój plik nginx.conf. Usunąłem części SSL, ale możesz po prostu wstawić własne. Zauważ, że potrzebujesz nginx 1.4+, ponieważ wszystko przed tą wersją nie obsługuje websocket proxying.

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

Czytałem gdzieś, że allowed_request_origins nie działa zgodnie z oczekiwaniami, więc poszedłem bezpieczną drogę (dopóki błąd jest stały) i okazało się, że sprawdzanie całkowicie przy użyciu ActionCable.server.config.disable_request_forgery_protection = true.

Oto mój plik cable.ru do uruchomienia kabla akcji.

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 

Używam również najnowszej wersji szyn z Github.

gem "rails", github: "rails/rails"