Отправленные сервером события с модулем node.js http2 - как мне использовать его с stream / pushStream? - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь реализовать сервер, который отправляет большой объем данных (объекты, а не файлы) каждые 500 мс. После некоторого чтения события, отправленные сервером через http2, кажутся наиболее быстрым вариантом (поскольку http2 является двоичным протоколом, а SSE снижает накладные расходы на трафик)

После небольшой игры с SSE на http / 1.1 Я пытался сделать то же самое на http2. Я пытался сделать это с stream и pushStream , но безуспешно. Однако использование того же способа, что и для http / 1.1, похоже, работает.

Мой вопрос - почему сервер 1 (см. Ниже), который использует поток, не работает, а сервер 2, кажется, работает нормально? я что-то упускаю при работе потоков узлов?

Я использую узел v10.9.0 и хром 68.0.3440.106

Я прочитал следующие вопросы и сообщения, но все еще не смог решить эту проблему:

Сервер 1 - http2 с потоком (Не работает - клиент не получает события. Chrome описывает запрос как незавершенный запрос):

const fs = require('fs');
const http2 = require('http2');

const HTTPSoptions = {
    key: fs.readFileSync('./cert/selfsigned.key'),
    cert: fs.readFileSync('./cert/selfsigned.crt'),
};
const template = `
<!DOCTYPE html> 
<html>
<body>
    <script type="text/javascript">
        const  source = new EventSource('/sse/');
        source.onmessage = function(e) { 
            document.body.innerHTML += e.data + '<br>';
        };
    </script>
</body>
</html>
`;


const server = http2.createSecureServer(HTTPSoptions);

server.on('stream', (stream, headers, flags) => {
    if (stream.url === 'sse/') {
        console.log(stream.respond);
        stream.respond({
            ':status': 200,
            'content-type': 'text/event-stream'
        });
        setInterval(() => stream ? res.write(`data: ${Math.random()}\n\n`) : '', 200);
    }
});

server.on('request', (req, res) => {
    if(req.url === '/') {
        res.end(template);
    }
});



server.listen(3001);

Сервер 2 - http2 с потоком (работает нормально):

const fs = require('fs');
const http2 = require('http2');

const HTTPSoptions = {
    key: fs.readFileSync('./cert/selfsigned.key'),
    cert: fs.readFileSync('./cert/selfsigned.crt'),
};
const template = `
<!DOCTYPE html> 
<html>
<body>
    <script type="text/javascript">
        const  source = new EventSource('/sse/');
        source.onmessage = function(e) { 
            document.body.innerHTML += e.data + '<br>';
        };
    </script>
</body>
</html>
`;


const server = http2.createSecureServer(HTTPSoptions);

server.on('request', (req, res) => {
    req.socket.setKeepAlive(true);

    if(req.url === '/sse/') {

        res.writeHead(200, {
            'Content-Type': 'text/event-stream', // <- Important headers
            'Cache-Control': 'no-cache'
        });
        res.write('\n');

        setInterval(() => res.write(`data: ${Math.random()}\n\n`), 200);
    } else {
        res.end(template);
    }
});

server.listen(3001);
...