2012-12-02 3 views
58

Auf der Serverseite mit Sinatra mit einem stream Block.EventSource/Server-Gesendete Ereignisse über Nginx

get '/stream', :provides => 'text/event-stream' do 
    stream :keep_open do |out| 
    connections << out 
    out.callback { connections.delete(out) } 
    end 
end 

Auf Client-Seite:

var es = new EventSource('/stream'); 
es.onmessage = function(e) { $('#chat').append(e.data + "\n") }; 

Wenn ich direkt mit App, über http://localhost:9292/, alles funktioniert perfekt. Die Verbindung ist dauerhaft und alle Nachrichten werden an alle Clients übergeben.

Jedoch, wenn es durch Nginx geht, http://chat.dev, wird die Verbindung fallen gelassen und eine Wiederverbindung wird jede Sekunde oder so ausgelöst.

Nginx Setup sieht für mich ok:

upstream chat_dev_upstream { 
    server 127.0.0.1:9292; 
} 

server { 
    listen  80; 
    server_name chat.dev; 

    location/{ 
    proxy_pass http://chat_dev_upstream; 
    proxy_buffering off; 
    proxy_cache off; 
    proxy_set_header Host $host; 
    } 
} 

Versuchte keepalive 1024 in upstream Abschnitt sowie proxy_set_header Connection keep-alive; in location.

Nichts hilft :(

keine persistenten Verbindungen und Nachrichten nicht an Kunden weitergegeben.

Antwort

122

Ihre Nginx Konfiguration korrekt ist, die Sie gerade verpassen paar Zeilen.

Hier ist ein „magisches Trio“ Herstellung EventSource Arbeits durch Nginx:

proxy_set_header Connection ''; 
proxy_http_version 1.1; 
chunked_transfer_encoding off; 

Platz sie in location Abschnitt und es sollte w Ork.

Sie können auch

proxy_buffering off; 
proxy_cache off; 

Das ist kein offizieller Weg, es zu tun hinzufügen müssen.

I endete mit dieser durch „Versuch und Irrtum“ up + „googeln“ :)

+0

Oh, das war es! Arbeite jetzt! Starten Sie meinen Über-Chat mit der Öffentlichkeit! Vielen Dank! –

+0

funktioniert es gut für meinen Nodejs Server mit ngix, ich benutze auch EventSource.thanks. –

+1

Funktioniert so gut. Mann, das war schwer zu debuggen. Vielen Dank! –

3

Diese Mitteilung nicht von Grund auf selbst schreiben. Nginx ist ein wundervoll geregelter Server und verfügt über Module, die SSE für Sie ohne Leistungseinbußen Ihres Upstream-Servers handhaben.

Check out https://github.com/wandenberg/nginx-push-stream-module

Die Funktionsweise ist der Teilnehmer (Browser SSE verwenden) eine Verbindung zu Nginx und die Verbindung hält dort an. Der Publisher (Ihr Server hinter Nginx) sendet auf einer entsprechenden Route einen POST an Nginx und in diesem Moment wird Nginx sofort an den wartenden EventSource-Listener im Browser weiterleiten.

Diese Methode ist wesentlich besser skalierbar, als wenn Ihr Ruby-Webserver diese "Long-Polling" SSE-Verbindungen verarbeitet.

Verwandte Themen