Не приходит ответ на Ajax-запрос при активном Server-sent events
во время работы server-sent events ajax-запросы подвисают, не получая ответа от скрипта, при этом скрипт исполняется корректно, но $.ajax().done молчит как убитый (через некоторое время умирая с 504). возможно, что-то не так с nginx? я попробовал популярные решения для проблем с SSE, но нет, ни в какую. при этом заметил странную закономерность: если попробовать сразу после service nginx restart (т.е. на свежезапущенном сервере), то ajax корректно получает свой 200 от callback.php, в то время как evtsource слушает heartbeat, но уже после первой перезагрузки страницы ajax работать перестаёт :)
JS:
PoolUpdatesLive();
$('button').on('click', function (){
$.ajax({
url: 'callback.php',
dataType: 'json',
type: 'POST'
}).done(function (data){
console.log(data);
})
})
function PoolUpdatesLive(){
const evtSource = new EventSource("stream.php",{ withCredentials: false });
window.onbeforeunload = function() {
evtSource.close();
}
evtSource.onmessage = function(event) {
console.log(event.data);
}
}
stream.php:
<?php
@ini_set('implicit_flush', 1);
@ob_end_clean();
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Access-Control-Allow-Origin: *");
header("X-Accel-Buffering: no");
if (ob_get_level() > 0) {
ob_start();
}
while (true)
{
echo "data: heartbeat\n\n";
flush();
sleep(3);
}
callback.php:
<?php
$sql = new mysqli('localhost','someuser','somepass','somebase');
$stmt = $sql->prepare('UPDATE mysql.SOMETABLE SET NAME="1" where UID="2"');
$stmt->execute(); //что угодно, на самом деле :) просто для примера: с реальными данными БД обновляется
echo json_encode('some response');
кусок site.nginx.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
location / {
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET';
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_buffer_size 0;
proxy_cache off;
}
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;