Я нахожусь в процессе внедрения сервера на основе Koa для SSE.Я сталкивался с той же проблемой, и вот мои мысли / рабочее решение:
Насколько я могу судить, причина, по которой onmessage и onerror продолжают вызываться, заключается в том, что объект EventSource на стороне клиентаиспускает событие ошибки.Это приводит к разрыву соединения, в результате чего клиент отправляет другой запрос на инициализацию потока на сервер.Отсюда процесс повторяется бесконечно.
На основании моего собственного тестирования EventSource выдает ошибку из-за данных, которые отправляются обратно с сервера.В соответствии с docs ответ 200, имеющий тип контента, отличный от 'text / event-stream', вызовет ошибку.
В вашем примере вы объявили свой ответ как 'text / event-stream 'и передают строку в метод ctx.res.write.Хотя это выглядит правильно и фактически работает при использовании сопоставимого кода и Express, похоже, что это не работает в Koa.Однако, если вы измените «данные», которые вы записываете в свой ответ потоку, например, в этом примере здесь , вы обнаружите, что соединение установлено правильно.
Возможно, попробуйтеследующее:
//require Passthrough
const PassThrough = require('stream').PassThrough;
//then, in your writeSSE function, try this:
let stream = new PassThrough();
stream.write(`data: ${message}\n\n`);
ctx.res.write(stream);
Я не уверен на 100%, почему это изменение работает.Мое лучшее предположение состоит в том, что в объекте Koa ctx есть что-то, что препятствует тому, чтобы обычная строка или литерал шаблона рассматривались как допустимые данные текста / потока событий, но это полностью предположение (это вызывает вопрос о том, почему он работает в Express,но, надеюсь, кто-то более знающий может ответить на это для нас обоих).Из того, что я видел в других фрагментах, опубликованных в Интернете, в Koa можно использовать потоковый подход.
Я не уверен, каковы будут ваши результаты, так как похоже, что вы используете другойверсия Коа, чем я, но я бы дал ему шанс.Я смог правильно установить соединение, сделав это небольшое изменение.