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