Ошибка при получении сообщений SSE, угловой интерфейс, внутренний узел - PullRequest
0 голосов
/ 24 августа 2018

Я использую SSE для отправки простых сообщений из бэкэнда Node в приложение Angular. Пока это работает безупречно, но сегодня я понял, что это больше не работает, и я не могу найти причину.

Это соответствующий код:

УЗЕЛ

router.get('/stream', function (req, res) {
    [ ... ]

    // Send headers for event-stream connection
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });
    res.write('\n');

    [ ... ]
    // NOTE: This line connects to a Redis server
    subscriber.subscribe(channel);

    // In case we encounter an error...print it out to the console
    subscriber.on("error", function (err) {
        logger.debug("Redis Error: " + err);
    });

    // When we receive a message from the Redis connection
    subscriber.on("message", function (channel, message) {
        logger.debug('MESSAGE RECEIVED: ' + message);   // This message is printed in the log file

        [ ... ]
        // Note: 'msgData' is obtained by parsing the received 'message'
        // Send data to the client
        res.write('data: ' + msgData + "\n\n");
    });
}

Угловое приложение

declare var EventSource : any;

getSSEMessages(): Observable<string> {
    let sseUrl = `${ConfigService.settings.appURL}/stream`;    

    return new Observable<string>(obs => {
        const es = new EventSource(sseUrl, { withCredentials: true });  

        // This prints '1' (CONNECTION OPEN)
        console.log('SSE Connection: ', es.readyState);               

        // Note: I've also tried 'es.onerror'
        es.addEventListener("error", (error) => {
            console.log("Error in SSE connection", error);

            return false;
        });

        // Note: I've also tried 'es.onmessage'
        es.addEventListener("message", (evt : any) => {
            // Never gets in here
            console.log('SSE Message', evt.data);

            obs.next(evt.data);
        });

        return () => es.close();
    });
}

Вот как я получаю сообщения при выборе опции в интерфейсе:

this.getSSEMessages()
  .subscribe(message => {
    // SHOW MESSAGE TO THE USER
});

Как я уже говорил, все недели работало нормально. Сегодня я увидел, что не получаю никаких сообщений, и я пытался выяснить причину без удачи.

Есть какие-нибудь подсказки, что может быть не так?

1 Ответ

0 голосов
/ 30 августа 2018

Наконец-то я нашел решение:

Возможно, из-за обновления некоторых модулей Node или самого Node, он добавил своего рода буфер для оптимизации трафика соединения. Чтобы приложение снова заработало, все, что мне нужно было сделать, это добавить flush после каждого сообщения, например:

[...]
res.write('data: ' + msgData + "\n\n");

// Send the message instantly
res.flush();
[...]

Приветствия

...