如何关闭 Nginx 服务器上服务器发送事件的缓冲

Pra*_*kar 6 nginx nginx-reverse-proxy nginx-config

问题:Nginx 服务器正在缓冲服务器发送的事件(SSE)。

设置:节点 v12.13.1、Nginx 1.16.1、Chrome v80

场景:我尝试关闭缓冲,proxy_buffering off;甚至添加"X-Accel-Buffering": "no"到服务器响应标头中,但 nginx 仍在缓冲所有 SSE。如果我关闭节点服务器或重新启动 nginx 服务器,则所有 SSE 消息都会批量传递到客户端。我尝试了很多,但不知道我失踪了。

Nginx 配置文件:


events {
    worker_connections  1024;
}

http {
    include       mime.types;
    sendfile        on;   
    keepalive_timeout  65;

    server {
        listen       4200;
        server_name  localhost;

        location / {    
            proxy_set_header Connection '';
            proxy_http_version 1.1;
            chunked_transfer_encoding off;
            proxy_buffering off;
            proxy_cache off;
            proxy_pass http://localhost:8700;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

节点服务器:

var express = require('express');
var app = express();

var template = 
`<!DOCTYPE html> <html> <body>
    <script type="text/javascript">
        var source = new EventSource("/events/");
        source.onmessage = function(e) {
            document.body.innerHTML += e.data + "<br>";
        };
    </script>
</body> </html>`;

app.get('/', function (req, res) {
    res.send(template); // <- Return the static template above
});

var clientId = 0;
var clients = {}; // <- Keep a map of attached clients

// Called once for each new client. Note, this response is left open!
app.get('/events/', function (req, res) {
    req.socket.setTimeout(Number.MAX_VALUE);
    res.writeHead(200, {
        'Content-Type': 'text/event-stream', // <- Important headers
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'X-Accel-Buffering': 'no'
    });
    res.write('\n');
    (function (clientId) {
        clients[clientId] = res; // <- Add this client to those we consider "attached"
        req.on("close", function () {
            delete clients[clientId]
        }); // <- Remove this client when he disconnects
    })(++clientId)
});

setInterval(function () {
    var msg = Math.random();
    console.log("Clients: " + Object.keys(clients) + " <- " + msg);
    for (clientId in clients) {
        clients[clientId].write("data: " + msg + "\n\n"); // <- Push a message to a single attached client
    };
}, 2000);

app.listen(process.env.PORT || 8700);
Run Code Online (Sandbox Code Playgroud)

vad*_*vad 1

就我而言(我遇到了同样的问题),它是 nginx 前面的 nginx:即使您设置了x-accel-buffering: no,内部 nginx 也会“吃掉”它,而外部 nginx 会缓冲响应。如果是这种情况,您可以通过以下方式传递标头:

proxy_pass_header X-Accel-Buffering;
Run Code Online (Sandbox Code Playgroud)