EventSource / Eventos enviados por el Servidor a través de Nginx


En el lado del servidor usando Sinatra con un bloque 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 a través de Nginx, http://chat.dev, la conexión se cae y una 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;
  }
}

Intentado {[6] {} en[7]} sección así como proxy_set_header Connection keep-alive;en location.

Nada ayuda : (

No hay conexiones persistentes y mensajes no pasados a ningún cliente.

Author: Lukas Mayer, 2012-12-02

3 answers

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

Aquí está un" trío mágico " haciendo EventSource trabajando a través de Nginx:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

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

Es posible que también necesite agregar

proxy_buffering off;
proxy_cache off;

Esa no es una forma oficial de hacerlo.

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

 126
Author: Inaimathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 22:18:57

Otra opción es incluir en su respuesta un encabezado 'X-Accel-Buffering' con el valor 'no'. Nginx lo trata especialmente, véase http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

 5
Author: E1.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-17 23:02:51

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

Echa un vistazo 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 MENSAJE a Nginx en una ruta correspondiente y en ese moment Nginx se enviará inmediatamente al oyente 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 "sondeo largo".

 4
Author: Martin Konecny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-14 20:42:55