ruby nginx sinatra

ruby - Eventos EventSource/Server-Enviado a través de Nginx



sinatra (3)

En el lado del servidor usando Sinatra con un bloque de stream .

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

En el lado del cliente:

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

Cuando uso la aplicación directamente, a través de http://localhost:9292/ , todo funciona perfecto. La conexión es persistente y todos los mensajes se pasan a todos los clientes.

Sin embargo, cuando pasa por Nginx, http://chat.dev , la conexión se interrumpe y la reconexión se dispara cada segundo más o menos.

La configuración de Nginx me parece bien:

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

Intentó keepalive 1024 en la sección upstream así como proxy_set_header Connection keep-alive; en el location

Nada ayuda :(

No se transmiten conexiones ni mensajes persistentes a ningún cliente.


No escribas esto desde cero tú mismo. Nginx es un maravilloso servidor con evented y tiene módulos que manejarán SSE por usted sin ninguna degradación del rendimiento de su servidor en sentido ascendente.

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

La forma en que funciona es que el suscriptor (navegador que usa SSE) se conecta a Nginx, y la conexión se detiene allí. El editor (su servidor detrás de Nginx) enviará un POST a Nginx en la ruta correspondiente y en ese momento Nginx lo reenviará inmediatamente al oyente de EventSource en espera en el navegador.

Este método es mucho más escalable que tener su servidor web Ruby manejando estas conexiones SSE de "larga votación".



Tu configuración de Nginx es correcta, solo faltas algunas líneas.

Aquí hay un "trío mágico" que hace que EventSource trabaje a través de Nginx:

proxy_set_header Connection ''''; proxy_http_version 1.1; chunked_transfer_encoding off;

Colóquelos en location sección de location y debería funcionar.

Es posible que también necesites agregar

proxy_buffering off; proxy_cache off;

Esa no es una forma oficial de hacerlo.

Terminé con esto por "prueba y errores" + "googlear" :)