【问题标题】:socket.io emits multiple timessocket.io 发出多次
【发布时间】: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) 

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

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

【问题讨论】:

  • 你是怎么解决这个问题的???

标签: node.js express socket.io


【解决方案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。
    猜你喜欢
    • 2021-12-31
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 2018-06-16
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    相关资源
    最近更新 更多