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