отправленные сервером события создают слишком много слушателей для одного клиента - PullRequest
0 голосов
/ 15 января 2020

Я использую отправленные сервером события в MEAN стек. Я могу отправить данные sh с сервера на клиент при необходимости.

Но я заметил одну вещь: даже если я единственный клиент, попавший на сервер. Для меня есть несколько слушателей , и события транслируются, чтобы сказать: 40 слушателей (, если я подожду достаточно долго, чтобы клиент повторно подключился 40 раз ).

Несколько слушателей также создаются, когда пользователь перезагружает .

Как я могу ограничить слушателей, чтобы они говорили 1 слушателя на каждое событие на клиент . Возможно ли это даже с событиями, отправленными сервером.

Я пытаюсь держать соединение открытым, пока пользователь использует веб-сайт и закрывается, только когда браузер / вкладка закрыт или клиенты запросить перезагрузку.

NOTE : stream - это EventEmitter объект, который я использую для передачи событий, чтобы можно отслеживать необходимые изменения и отправлять соответствующие данные через отправленные сервером события.

const function = async (request: Request, response: Response) => {
    console.log("client connected to broadcasting channel")
    console.log("listeners : " , stream.listenerCount('event-L'))
    response.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        "X-Accel-Buffering": "no"
    });
    response.flushHeaders();

    stream.on('event-L', (event, data) => {
            console.log("Broadcasting event-L")
            response.write('event: ' + event + '\n' + 'data:' + JSON.stringify(data) + '\n\n')
        }
    })


    stream.on('event-U', (event, data) => {
            console.log("Broadcasting event-U.")
            response.write('event: ' + event + '\n' + 'data:' + JSON.stringify(data) + '\n\n')
        }

    })

    response.on('close', () => {
        console.log('client dropped me');
        response.end();
    })
}

1 Ответ

0 голосов
/ 16 января 2020

Когда клиент закрывает сокет, вы должны закрыть объект ответа на стороне сервера, который обслуживал его.

По крайней мере, при непосредственном использовании пакета http код выглядит примерно так:

request.connection.on("close", function(){
  response.end();
  //Any other clean up, e.g. clearInterval() for any timers.
  console.log("Client closed connection. Aborting.");
  });

Это было скопировано с п.25 моей книги, Data Pu sh Приложения с HTML5 SSE.

При { ссылка } есть пример для Express. js, который они записывают так:

response.on('close', () => {
  console.log('client dropped me');
  //Any other clean up
  response.end();
  });

Если предположить, request.connection и response - это один и тот же объект, то это один и тот же код, и, следовательно, не указан c до Express.

ОБНОВЛЕНИЕ на основе рассматриваемого кода

Ваши stream.on() вызовы добавляют слушателя к событию. Поэтому они являются частью «очистки», которую вы должны выполнять, когда клиент отключается. Т.е.

response.on('close', () => {
  console.log('client dropped me');
  response.end();
  stream.off('event-L', eventLHandler);
  stream.off('event-U', eventUHandler);
  })

См. https://nodejs.org/api/events.html#events_emitter_off_eventname_listener

Обратите внимание, как вам нужно указать функцию обработчика событий, поэтому нельзя использовать анонимные функции. Рефакторинг вашего кода, чтобы иметь два обработчика событий (которые принимают ответ как аргумент).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...