hapi 18 eventourcing не работает без stream.end () - PullRequest
0 голосов
/ 17 июня 2019

Попробуйте в архив:

Я пытаюсь использовать HTML5 EventSourcing API https://developer.mozilla.org/de/docs/Web/API/EventSource для отправки событий в мое клиентское приложение (javascript).

рабочий пример кода с простым узлом http:

С простым примером реализации узла он работает отлично и как ожидалось. Пример кода: https://www.html5rocks.com/en/tutorials/eventsource/basics/

Проблема:

Когда я пытаюсь интегрировать EventSourcing (или SSE) в мою конечную точку API, которая основана на хапи (в настоящее время используется последняя версия - 18.1.0), она не работает.

Мой код обработчика маршрута смешан с некоторым кодом, который я нашел:

const Stream = require('stream');

class ResponseStream extends Stream.PassThrough {
    setCompressor (compressor) {
        this._compressor = compressor;
    }
}

const stream = new ResponseStream();
let data = 0;

setInterval(() => {
    data++;
    stream.write('event: message\n');
    stream.write('data:' + data + '\n\n');
    console.log('write data...', data);
    // stream.end();        
}, 1000);

return h
    .response(stream)
    .type('text/event-stream')
    .header('Connection', 'keep-alive')
    .header('Cache-Control', 'no-cache')

Выводы:

Я уже искал, и, похоже, с hapi 17.x там они раскрыли метод очистки для компрессора <<a href="https://github.com/hapijs/hapi/issues/3658" rel="nofollow noreferrer">https://github.com/hapijs/hapi/issues/3658>, особенности раздела. Но это все еще не работает.

Единственный способ отправить сообщение - это раскомментировать строку stream.end () после отправки данных. Проблема, очевидно, в том, что я не могу отправить дополнительные данные, если закрою поток: /.

Если я убью сервер (с комментариями в строке stream.end ()), данные будут переданы клиенту в виде "одиночной передачи". Я думаю, что проблема все еще где-то с буферизацией gzip даже при очистке потока.

В hapi github есть несколько примеров кода, но ни один из них не работает с hapi 17 или 18 (все примеры, где hapi = <16): / </p>

Кто-то знает, как решить проблему, или у вас есть работающий пример EventSource с последним хапи? Буду признателен за любую помощь или предложения.

Редактировать - Решение

Решение из поста ниже работает, но у меня также был обратный прокси-сервер nginx перед моей конечной точкой api. Кажется, основная проблема была не в моем коде, а в nginx, который также буферизовал сообщения источника событий. Чтобы избежать такого рода проблем, добавьте в свой хапи: X-Accel-Buffering: нет; , и он работает безупречно

1 Ответ

0 голосов
/ 17 июня 2019

Ну, я только что протестировал с Hapi 18.1.0 и сумел создать рабочий пример.

Это мой код обработчика:

handler: async (request, h) => {
    class ResponseStream extends Stream.PassThrough {
        setCompressor(compressor) {
            this._compressor = compressor;
        }
    }

    const stream = new ResponseStream();

    let data = 0;

    setInterval(() => {
        data++;
        stream.write('event: message\n');
        stream.write('data:' + data + '\n\n');
        console.log('write data...', data);
        stream._compressor.flush();
    }, 1000);

    return h.response(stream)
        .type('text/event-stream')
}

и это код клиента просто для тестирования

var evtSource = new EventSource("http://localhost/");
evtSource.onmessage = function(e) {
    console.log("Data", + e.data);
};

evtSource.onerror = function(e) {
    console.log("EventSource failed.", e);
};

Это ресурсы, на которых я нашел свой пример работы

https://github.com/hapijs/hapi/blob/70f777bd2fbe6e2462847f05ee10a7206571e280/test/transmit.js#L1816

https://github.com/hapijs/hapi/issues/3599#issuecomment-485190525

These are my console results

...