多次发射

时间:2019-08-28 15:46:26

标签: node.js socket.io

我已经阅读了该网站并在Google上搜索过,似乎找不到适合我的答案。

我已经建立了一个使用Socket.IO的超级超级基本示例,直到可以理解为止,它所要做的就是将数字传递给后端,将+1加回并发送回前端。 / p>

它确实可以工作,但是每隔一个间隔,它就会发出越来越多的信号(我可以在服务器端使用console.log看到它。)我仅使用一台计算机进行连接即可进行测试。

有人可以帮我吗。我了解其原因可能是因为发射位于连接内部,但我无法完全克服如何克服这一问题。

我尝试过移动位,将功能移出连接。我已经尝试过Google的多个想法,但似乎没有任何解决办法。

const io = require('socket.io')();

io.on('connection', (socket) => {
  socket.on('subscribeToAddition', (additon,interval) => {
    console.log('current number... ', additon);
    setInterval(() => {
      socket.emit('addition', additon+1);
    }, interval);
  });
});

const port = 8000;
io.listen(port);
console.log('listening on port ', port);

时间间隔变量在我的react组件中设置为5秒。我只希望它每五秒钟记录一次/更新一次,而不是记录一次,然后记录两次,然后记录4次,然后记录8次,等等。

1 个答案:

答案 0 :(得分:0)

鉴于这些症状,很可能您在同一套接字上多次发送subscribeToAddition事件,从而为同一套接字启动了多个计时器,因此您收到重复的消息。


正确缩进代码可以使事情更清楚:

const io = require('socket.io')();

io.on('connection', (socket) => {

    socket.on('subscribeToAddition', (additon, interval) => {

        console.log('current number... ', additon);

        setInterval(() => {
            socket.emit('addition', additon + 1);
        }, interval);

    });

});

const port = 8000;
io.listen(port);
console.log('listening on port ', port);

我想确保您了解setInterval()会启动一个重复计时器,该计时器将一直持续到您对返回的timerId调用clearInterval()为止。

我看到的问题:

  1. 在每条subscribeToAddition消息中,您都添加了一个新的setInterval()计时器。因此,如果两次发送subscribeToAddition,则将有两个setInterval()计时器,每个计时器都在同一个套接字上。

  2. 那些setInterval()计时器将累积并且永远不会消失,因为您无法阻止客户端停止它们,即使套接字关闭,它们也不会消失。它们只会引起错误,因为socket.emit()不能在封闭的套接字上工作,但是它们甚至可能阻止旧套接字的垃圾回收。


尚不清楚您希望它如何工作,但这是一个清理后的版本:

const io = require('socket.io')();

io.on('connection', (socket) => {

    function clearTimer() {
        if (socket.myTimer) {
            clearInterval(socket.myTimer);
            delete socket.myTimer;
        }
    }

    socket.on('subscribeToAddition', (additon, interval) => {

        console.log('current number... ', additon);

        // don't start a new interval timer if one is already running
        if (!socket.mytimer) {

            socket.mytimer = setInterval(() => {
                socket.emit('addition', ++additon);
            }, interval);
        }

    });

    socket.on('unSubscribeToAddition', () => {
        clearTimer();
    });

    socket.on('disconnect', () => {
        clearTimer();
    });

});

const port = 8000;
io.listen(port);
console.log('listening on port ', port);

此版本进行了以下修改:

  1. 跟踪setInterval()中的timerID,以便我们将来将其停止。为了方便起见,我们将其作为自定义属性存储在套接字对象上,以便每个连接的套接字都有自己的计时器。
  2. 添加一条unsubscribeToAddition消息,以便客户端可以停止计时器。
  3. 添加一个disconnect消息处理程序,以便在套接字断开连接时停止计时器。
  4. 在计时器的每个刻度上增加additon变量。