EventSource / Server-отправленные события через Nginx

на стороне сервера с помощью Sinatra с stream заблокировать.

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

на стороне клиента:

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

когда я использую приложение напрямую, через http://localhost:9292/, все идеально работает. Соединение является постоянным, и все сообщения передаются всем клиентам.

однако, когда он проходит через Nginx,http://chat.dev подключение и переподключение срабатывает каждый второй или так.

настройка Nginx выглядит нормально для меня:

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

попытался keepalive 1024 на а также proxy_set_header Connection keep-alive;на location.

ничего не помогает :(

нет постоянных соединений и сообщений, не передаваемых клиентам.

3 ответов


ваша конфигурация Nginx верна, вы просто пропустите несколько строк.

вот" волшебное трио " делает EventSource работа через Nginx:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

разместить их в и он должен работать.

вам также может потребоваться добавить

proxy_buffering off;
proxy_cache off;

это не официальный способ сделать это.

Я закончил это с помощью "проб и ошибок" + "googling":)


другой вариант-включить в свой ответ заголовок "X-Accel-Buffering" со значением "no". Nginx обрабатывает его специально, см.http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering


Не пишите это с нуля самостоятельно. Nginx-замечательный сервер evented и имеет модули, которые будут обрабатывать SSE для вас без ухудшения производительности вашего вышестоящего сервера.

проверить https://github.com/wandenberg/nginx-push-stream-module

Как это работает, абонент (браузер с помощью SSE) подключается к Nginx, и соединение останавливается там. Издатель (ваш сервер за Nginx) отправит сообщение в Nginx по соответствующему адресу route и в этот момент Nginx сразу же переадресует ожидающий прослушиватель EventSource в браузере.

этот метод гораздо более масштабируемый, чем ваш веб-сервер ruby обрабатывает эти соединения SSE с "длинным опросом".