SocketIO 限制进度观看请求

SocketIO limit requests on progress watching

我正在将 SocketIO 用于一个小型应用程序,只要发生更改,用户就会收到更新。但是,我想实现它以在服务器端完成的任务中实现实时进度可视化。

但是,如果任务进度变化太快,这将导致大量事件排放,我认为这可能会降低应用程序性能。有没有办法将事件发射限制为每秒最多 N 次(仅发射最后一个,进度的最后一个百分比)?

是的,可以做到。它要求您将事件保持一小段时间,以查看是否有更多同类事件到来,从而将所有事件合并为一个。我将在几分钟内编写一个示例。

以下是您如何执行此操作的一般思路:

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 毫秒的更新,只发送最后一次更新。同样,您可以根据自己的喜好设置这些数字。