2016-03-28 10 views
9

Ich habe kürzlich mein Rails-Projekt von Rails4 auf 5.0.0.beta3 umgestellt, um das tolle ActionCable zu verwenden.Wie konfiguriere ich ActionCable mit Nginx und Unicorn in der Produktion?

Mein ActionCable-Server wird im Unicorn ausgeführt. In der Entwicklung funktioniert alles gut. In der Produktion habe ich

Started GET "/cable" for xxx.xxx.xxx.xxx at 2016-03-28 18:06:38 +0300 
Started GET "/cable/" [WebSocket] for xxx.xxx.xxx.xxx at 2016-03-28 18:06 
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) 
Registered connection (189772ff-6229-48f1-ae7f-d9a96ad3a6c3) 
Finished "/cable/" [WebSocket] for xxx.xxx.xxx.xxx at 2016-03-28 18:06:35 

Und diese Botschaft wiederholt immer wieder in einer Schleife.

Ich habe eine Menge Optionen bei Stackoverflow ausprobiert, um damit umzugehen, aber nichts hilft. Meine nginx config:

upstream unicorn { 
    server unix:/tmp/unicorn.my_app.sock fail_timeout=0; 
} 

server { 
    server_name www.my_app.com; 
    return 301 $scheme://my_app.com$request_uri; 
} 

server { 
    listen 80 default deferred; 
    server_name my_app.com; 
    root /var/www/my_app/current/public; 

    location ^~ /assets/ { 
    gzip_static on; 
    expires max; 
    add_header Cache-Control public; 
    } 

    try_files $uri/index.html $uri @unicorn; 
    location @unicorn { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off; 
    proxy_pass http://unicorn; 
    } 

    location /cable { 
    proxy_pass http://unicorn/cable; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade websocket; 
    proxy_set_header Connection Upgrade; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 

    error_page 500 502 503 504 /500.html; 
    keepalive_timeout 5; 
} 

Um sicher zu sein, dass Anfrage Ich habe diesen Code vorübergehend erlaubt ist, in initializers verwenden: ActionCable.server.config.disable_request_forgery_protection = true

Meine cable.coffee Datei

@App ||= {} 
App.cable = ActionCable.createConsumer "/cable" 

Meine config/cable.yml Datei

production: 
adapter: redis 
url: redis://localhost:6379/1 

Ich bin nicht so erfahren in dieser Frage, so jede Hilfe wäre toll.

+0

Haben Sie 'mount ActionCable.server => '/ cable' in Ihren Routen? – siegy22

+0

@yzalavin Konnten Sie das lösen? Ich sehe das gleiche Problem. –

+0

@R_G Ich habe das gleiche Problem. Konntest du die Probleme finden? Von dem, was ich debugged habe, ist Unicorn nicht in der Lage, Ping zu den Clients zu senden und so versucht der Client, die Verbindung wiederherzustellen. Also die connect-Anweisungen in Schleife. Nicht sicher, warum der Fluss in der anderen Richtung nicht funktioniert – sethi

Antwort

1

Ich implementierte rack-timeout. Das Einstellen der richtigen Timeouts hat mein Problem korrigiert. Die richtige Methode, diese Variablen zu setzen, ist in einer Erklärung config.ru Verwendung wie folgt:

use Rack::Timeout, service_timeout: 5 
0

Dies ist Config, die ich für meine Website, und es scheint zu funktionieren (Rails 5 + Nginx + Einhorn + Capistrano). Includes Sie sehen in dem Snippet sind von h5bp/server-configs-nginx, aber ich glaube nicht, dass sie ein Grund sein könnten, warum Ihre Konfiguration nicht funktioniert.

upstream example_app { 
    server unix:/home/username/www/example.com/current/tmp/sockets/unicorn.example.com.sock fail_timeout=0; 
} 

server { 
    listen 80; 
    server_name example.com www.example.com; 

    return 301 https://example.com$request_uri; 
} 

server { 
    listen 443 ssl; 
    server_name www.example.com; 

    include h5bp/directive-only/ssl.conf; 
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; 

    return 301 https://example.com$request_uri; 
} 

server { 
    listen 443 ssl; 
    server_name example.com; 

    include h5bp/directive-only/ssl.conf; 
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; 

    root /home/username/www/example.com/current/public; 

    # Set maximum request body size for uploads 
    client_max_body_size 25m; 

    try_files $uri/index.html $uri @unicorn; 
    location @unicorn { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_set_header X-Forwarded-Proto https; 
    proxy_redirect off; 
    proxy_pass http://example_app; 
    } 

    location /cable { 
    proxy_pass http://example_app; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade websocket; 
    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; 
    } 

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

    charset utf-8; 
    server_tokens off; 

    error_page 404 /404.html; 

    include h5bp/basic.conf; 
} 

cable.yml

production: 
    adapter: redis 
    url: redis://localhost:6379/1 

cable.js

//= require action_cable 
//= require_self 
//= require_tree ./channels 

(function() { 
    this.App || (this.App = {}); 

    App.cable = ActionCable.createConsumer(); 

}).call(this); 
3

Im location /cable Abschnitt benötigen eine Linie proxy_set_header Host $http_host;

Sollte hinzuzufügen:

location /cable { 
    proxy_pass http://unicorn/cable; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade websocket; 
    proxy_set_header Connection Upgrade; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    } 
+0

das hat für mich funktioniert :) –