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 59

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 с "длинным опросом".