socket.io 发出多次

Posted

技术标签:

【中文标题】socket.io 发出多次【英文标题】:socket.io emits multiple times 【发布时间】:2015-11-22 19:13:56 【问题描述】:

我有一个非常基本的例子。这个问题之前在堆栈溢出本身中已经被问过多次,但我无法得到正确的答案,所以我将使用这个基本示例。

服务器:

var app    = require('express')();
var server = require('http').Server(app);
var io     = require('socket.io')(server);

server.listen(3000);

app.get('/', function (req, res) 
  res.sendfile(__dirname + '/index.html');
);

io.on('connection', function (socket) 
  socket.on('chat', function (data) 
    var op = false;
    if( data.id == '1234' )
       op = 'yes';
    else
       op = 'no';
     
    socket.emit('result',  hello: op );
  );
);

客户:

<html>
    <body>
        <button onclick="check()">Test Me :-)</button>
        <script src="/socket.io/socket.io.js"></script>
        <script>
          var socket = io.connect('http://localhost:3000');

          var check = function()

            var data =  id : '234';
            socket.emit('chat', data);

            socket.on('result', function(data)
                console.log('The data is '+data)
            )
          
        </script>
    </body>
</html>

当我第一次点击测试我按钮时 socket.emit('结果', 你好:'世界' ); 它被发射一次。在控制台中,我正在打印:

console.log('The data is '+data)

但是当我再次点击时,我会打印三次:

console.log('The data is '+data)
console.log('The data is '+data)
console.log('The data is '+data)

当我第三次点击时,我会打印六次:

console.log('The data is '+data)
console.log('The data is '+data)
console.log('The data is '+data)
console.log('The data is '+data)
console.log('The data is '+data)
console.log('The data is '+data) 

像这样它正在繁殖和发展。

谁能告诉我如何解决这个问题。 非常感谢您的帮助。谢谢!

【问题讨论】:

你是怎么解决这个问题的??? 【参考方案1】:

我认为您正在为每个要检查的呼叫添加越来越多的“结果”听众。

第一次点击 -> 从调用 1 监听器调用 1 控制台日志

第二次点击 -> 从调用 1 监听器调用 1 console.log + 从调用 1 监听器调用 2 console.log + 从调用 2 监听器调用 2 console.log

第三次 -> 之前的日志 + 从调用 1 监听器调用 3 console.log + 从调用 2 监听器调用 3 console.log 并从调用 3 监听器调用 3 console.log。

尝试将“结果”的侦听器置于函数之外:

<html>
 <body>
    <button onclick="check()">Test Me :-)</button>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io.connect('http://localhost:3000');

       socket.on('result', function(data)
            console.log('The data is '+data)
        )
      var check = function()

        var data =  id : '234';
        socket.emit('chat', data);
      
    </script>
 </body>
</html>

【讨论】:

【参考方案2】:

对于客户端,您可以使用socket.once() 而不是socket.on()。示例:

socket.once('result', function(data)
 console.log('The data is '+data)
)

参考:https://socket.io/docs/v3/listening-to-events/#socket-once-eventName-listener

【讨论】:

这对我有用,谢谢【参考方案3】:

我没有阅读这个问题,但我把它放在这里是为了帮助其他人,因为我还没有找到这种答案。

就我而言,我多次调用函数next,就像这样

io.use(async (socket, next) => 
    let req = socket.request
    let res = req.res || 

    someMiddleware()(req, res, next)
    anotherMiddleware(extended: false)(req, res, next)
    anotherMiddleware()(req, res, next)
    anotherMiddleware(req, res, next)
    anotherMiddleware()(req, res, next)
    anotherMiddleware()(req, res, next)
)

每次我调用中间件时,next 函数都会被调用,on('connection') 也会被调用。我要做的是覆盖next 并将其放在最后一个中间件中,这样连接只会被调用一次。

. . .
let originalNext = next
next = () =>  // NOW its not going to annoy anymore
someMiddleware()(req, res, next)
anotherMiddleware(extended: false)(req, res, next)
anotherMiddleware()(req, res, next)
anotherMiddleware(req, res, next)
anotherMiddleware()(req, res, next)
anotherMiddleware()(req, res, originalNext) //next get called <
. . . 

【讨论】:

我不明白你为什么在没有 await 的情况下调用 async func。

以上是关于socket.io 发出多次的主要内容,如果未能解决你的问题,请参考以下文章

Socket.IO 在一个房间内多次发射(与 React.js 一起使用)

Socket IO事件多次触发NodeJS

socket.io - 多次加载视图时,socket.on 方法也会运行多次

Node.js socket.io 没有响应 iOS socket.io 发出请求

Socket.io 未能发出函数

socket.io 发出不接收消息的原因?