Отправляйте событие отправки сервера (SSE) каждый раз, когда в NodeJs достигается конечная точка API. - PullRequest
0 голосов
/ 21 ноября 2019

Я пытаюсь реализовать способ отправки отправленного сервером события (SSE) в NodeJ каждый раз, когда достигается конечная точка моего сервера.

Вот как я добился этого

//...code...
import EventSource from "eventsource";

const EventEmitter = require('events');
const events = new EventEmitter();
// events.setMaxListeners(10);


// api end point route from where the new order requests will be coming
router.route('/new-order')
  .post((req, res) => {
    const orderData = req.body.data;
    //... save order and emit an event to send response to the client react app
    events.emit('newOrder', orderData);
  });

// define a function to send SSE events to the client
const sse = res => data => {
  const dataToSend = JSON.stringify(data);
  res.write(`data:${dataToSend}`);
  res.write("\n\n");
};

// define an EventSource route for the client to be connected for new events
router.route('/sse')
  .get((req, res) => {

    res.writeHead(200, {
      "Connection": "keep-alive",
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
    });

    res.write("\n");

    const sendSSE = sse(res);
    /*
    PROBLEMATIC CODE-- EACH request to /sse route adds new event listener,
    and in minutes, it exceeds the limit of maxListeners, and I get the warning 
    to increase the max event listeners limit by using setMaxListeners()
    even if only 1 user is using the front end app.
    */
    events.on('newOrder', sendSSE);
  });

//...Code...


// Client Side
const newOrderReceived = (e) => {
  console.log(JSON.parse(e.data));
};

if ( !window.eventSource ) {
  window.eventSource = new EventSource('https://example.com/sse');
  window.eventSource.onmessage = newOrderReceived;
}

Но проблема в том, что maxListeners исчерпывают с очень высокой скоростью, даже если приложение использует только 1 пользователь.

Если я изменю код привязки события на

events.once('newOrder', sendSSE);

событияОшибка maxListeners исчезает, но она не уведомляет мое приложение после первого заказа. Я не могу найти способ привязать событие из моего /sse маршрута, потому что мне нужно отправить данные по

res.write(`data:${dataToSend}`);
res.write("\n\n");

, и этот объект res доступен только внутри маршрута в моем случае/sse.

Каким может быть решение этой проблемы или есть ли лучший подход для отправки отправленного сервером события (SSE) в NodeJS, чтобы уведомлять мое приложение переднего плана каждый раз, когда я получаю запрос от своегоКонечная точка API?

Любая помощь будет принята с благодарностью.

PS: Все учебные пособия / руководства, которые я видел при поиске по этой проблеме, реализуют setInterval внутри маршрута. для отправки данных я не нашел учебника, в котором объясняется, как отправлять данные в ответ на событие на сервере.

...