SocketIO ограничивает запросы на отслеживание прогресса - PullRequest
0 голосов
/ 19 марта 2020

Я использую SocketIO для небольшого приложения, где пользователи будут получать обновления при каждом изменении. Тем не менее, я хотел бы реализовать его для визуализации прогресса в реальном времени в задачах, выполняемых на стороне сервера.

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

1 Ответ

0 голосов
/ 19 марта 2020

Да, это можно сделать. Это требует от вас провести события на короткое время, чтобы увидеть, не появятся ли еще события того же рода, и таким образом объединить их все в одно. Я напишу пример через несколько минут здесь.

Вот общая идея, как вы могли бы сделать это:

function emitMessageLast(socket, msg, data) {
    const queueTime = 500;           // wait for up to 500ms of idle time before sending latest data
    const longestWaitTime = 2000;    // wait no more than 2 seconds if data is being continuously sent

    function stopTimer() {
        if (socket._timer) {
            clearTimeout(socket._timer);
            socket._timer = null;
        }
    }

    function sendNow() {
        socket._lastMsg = msg;
        socket._lastTime = Date.now();
        return socket.emit(msg, data);
    }

    // if this is the first time we're sending this message
    // or it's been awhile since we last sent data
    // just send the new data immediately
    if (socket._lastMsg !== msg || !socket._lastTime || Date.now() - socket._lastTime > longestWaitTime) {
        stopTimer();
        return sendNow();
    }

    // at this point, we know we're sending the same message as has recently been sent
    socket._lastMsg = msg;
    socket._lastData = data;
    stopTimer();
    // set a timer so that if no more data has arrived before the timer fires, 
    // we sent the last data we saved
    socket._timer = setTimeout(() => {
        socket._timer = null;
        sendNow();
    }, queueTime);
}

Общая идея этого кода следующая:

  1. Когда вам звонят с сообщением для отправки, и ни одно сообщение того же типа не было недавно отправлено, немедленно отправьте это сообщение и запишите время его отправки.
  2. Когда вы получите вызвано с сообщением для отправки, и прошло более longestWaitTime с тех пор, как вы последний раз отправляли сообщение, а затем отправьте это немедленно. Это означает, что если сервер непрерывно отправляет данные, он будет ждать до longestWaitTime, прежде чем отправлять последнее значение данных.
  3. Когда сервер отправляет данные спорадически, он будет ожидать до queueTime (ожидание, чтобы увидеть, есть ли еще данные) перед отправкой последнего фрагмента данных. По сути, он буферизует последнее сообщение, пока в последнем queueTime не будет отправлено больше сообщений, и затем таймер сработает из этого последнего сообщения.
  4. Я настроил значения по умолчанию, чтобы задержать отправку данные клиенту в течение до 500 мс (в ожидании, чтобы увидеть, собирается ли сервер отправить больше данных, чтобы он мог избежать отправки всех промежуточных значений данных), полагая, что, если клиент обновляет свой статус каждые 500 мс, это довольно часто , И, если сервер непрерывно отправляет обновления, сервер пропустит до 2000 мс обновлений, чтобы отправить только одно последнее обновление. Опять же, вы можете установить эти цифры, как считаете нужным.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...