Проблема с отправкой SSE из экспресса - PullRequest
0 голосов
/ 21 февраля 2019

Мы используем архитектуру микросервисов для нашего проекта.Наш проект похож на блог.Существует сервис actions , который регистрирует все действия, выполненные пользователем, такие как добавление сообщения, комментарий, ответ на комментарий и т. Д.

Теперь для каждого действия нам нужноотправить уведомление SSE вовлеченным пользователям.Для этого мы используем другой сервис под названием уведомления .Поэтому всякий раз, когда происходит какое-либо действие, HTTP-запрос отправляется в службу уведомлений, которая обрабатывает отправку различных событий SSE.

Однако мы сталкиваемся с некоторыми проблемами при отправке SSE.Две основные проблемы, с которыми мы сталкиваемся: утечка памяти и ошибка Ошибка: запись после завершения

Маршрут

router
    .route("/")
    .get(controller.eventStream)
    .post(controller.sendNotification);

Контроллер

import axios from "axios";
import eventEmitter from '../services';

const controller = {
  eventStream: (req, res, next) => {
    console.log("Inside event stream");
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      "Connection": "keep-alive"
    });

    eventEmitter.on("sse", (event, data) => {
      console.log('Event Triggered');
      res.write(`event: ${event}\ndata: ${JSON.stringify(data)} \n\n`);
    });

    req.on("close", () => {
      console.log("Inside Close");
      res.end();
    });
  },

  sendNotification: (req, res, next) => {
    try {
      const {
        userId,
        action,
        type,
        item_id,
      } = req.body;

      // First check the type of activity that has been performed
      switch (type) {
        case "topic":
          // Then check the type of action that has been done
          switch (action) {
            case "edit":
              console.log("Topic edited");
              const data= 'John Doe has edited a topic';
              eventEmitter.emit("sse", `edit-topic`, data);
              break;
          }
          break;
      }
      res.send('sse successfully send');
    } catch (error) {
      res.status(500).json({error: 'SSE failed'});
    }
  }
};

export default controller;

Сервис

export default new events.EventEmitter();

Первоначально клиентская сторона отправит запрос GET , который выполняетсяконтроллер eventStream.

Теперь для каждого действия необходимо отправить SSE через этот поток

Я считаю, Ошибка: запись после завершения , потому что событиесрабатывает после отправки respose.Это можно исправить, удалив res.send('sse successfully send'); Однако узел выдаст ошибку тайм-аута.

Я не уверен, как отправить SSE с контроллера sendNotification.Более того, я не уверен, что это правильный подход.Любое руководство будет высоко ценится.

...