如何使用 socket.io 和节点在循环中发出事件.js

How to emit events in loop using socket.io and node.js

提问人:User 提问时间:4/27/2023 更新时间:4/27/2023 访问量:113

问:

我想使用 socket.io 和 node.js 循环发出 5 条事件消息。

这是我到目前为止尝试过的:

HTML 客户端

//client
<!doctype html>
<html>
  <head>
    <title>Socket.IO DEMO - LOOP EMIT Events</title>
    <style>
    </style>
  </head>
  <body>
    <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
      var socket = io();
      var global_var = "";

      $(function () {
         //5 loops
          for( let i = 1; i <= 5; i++ ){
            manageEvents_v1(i)
              .then(message => {    
                console.log("call manageEvents_v1() - Promise resolved successfully - message: " + message);   
                //put received data in global variable 'global_var'
                global_var = message;
              })
              .catch(function() {
                console.log("call manageEvents_v1() - Promise is rejected");            
              });

              //use 'global_var' here, every loop, outside callback
            
          }
      });
      
      var manageEvents_v1 = function(data) {
        return new Promise(function(resolve, reject) {
          let timer;

          socket.emit('trigger', data);
      
          function response(message) {
            resolve(message);
            clearTimeout(timer);
            socket.removeListener('feedBack_trigger', response);
          }

          socket.on('feedback_trigger', response); 

          timer = setTimeout(() => {
            reject(new Error("timeout err!"));
            socket.removeListener('feedBack_trigger', response);
          }, 10000);
      
        });
      }

    </script>
  </body>
</html>

节点.JS服务器:

//server
//////////////////
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);
const session = require("express-session");
const bodyParser = require("body-parser");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;

var port = process.env.PORT || 9090;

const sessionMiddleware = session({ secret: "changeit", resave: false, saveUninitialized: false });
app.use(sessionMiddleware);

app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());

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

const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);
io.use(wrap(sessionMiddleware));
io.use(wrap(passport.initialize())); 
io.use(wrap(passport.session()));


io.sockets.on('connection', function(socket){
  var socketId = socket.id;
    var clientIp = socket.request.connection.remoteAddress;

  console.log("DEBUG - A user connected!");
    console.log("DEBUG - clientIp: " + clientIp + " || socketId: " + socketId);

  socket.on('trigger', function (data) {  
    console.log("\n ----------  BEGIN::EVENT -> trigger  -------------------- \n");
    console.log("DEBUG -> Data RECEIVED from CLIENT: " + data);
    console.log("DEBUG -> SEND back data to CLIENT: " + data);
    socket.emit('feedback_trigger', "hello from server - this is your data: " + data); // Send data to client
  });
});

////////// server listen //////////////////////////////////////////////////
server.listen(port, () => {
  console.log(`listening on *:${port}`);
});

在服务器控制台上,我有以下调试消息:

 ----------  BEGIN::EVENT -> trigger  --------------------

DEBUG -> Data RECEIVED from CLIENT: 1
DEBUG -> SEND back data to CLIENT: 1

 ----------  BEGIN::EVENT -> trigger  --------------------

DEBUG -> Data RECEIVED from CLIENT: 2
DEBUG -> SEND back data to CLIENT: 2

 ----------  BEGIN::EVENT -> trigger  --------------------

DEBUG -> Data RECEIVED from CLIENT: 3
DEBUG -> SEND back data to CLIENT: 3

 ----------  BEGIN::EVENT -> trigger  --------------------

DEBUG -> Data RECEIVED from CLIENT: 4
DEBUG -> SEND back data to CLIENT: 4

 ----------  BEGIN::EVENT -> trigger  --------------------

DEBUG -> Data RECEIVED from CLIENT: 5
DEBUG -> SEND back data to CLIENT: 5

正如你所看到的,服务器消息很好,但在客户端,我收到了类似的东西:enter image description here

我不知道为什么,但所有 5 个响应的第一个值都是“1”......我无法接收从 1 到 5 的所有值。

我希望服务器出现这样的事情,在每次从服务器发出事件后,都会看到一条具有正确值的消息,最后在浏览器控制台中,在所有 5 个循环结束后,显示:

call manageEvents_v1() - Promise resolved successfully - message: hello from server - this is your data: 1
call manageEvents_v1() - Promise resolved successfully - message: hello from server - this is your data: 2
call manageEvents_v1() - Promise resolved successfully - message: hello from server - this is your data: 3
call manageEvents_v1() - Promise resolved successfully - message: hello from server - this is your data: 4
call manageEvents_v1() - Promise resolved successfully - message: hello from server - this is your data: 5

之后,我需要 Promise 回调之外的这些值将它们分配给另一个全局变量 (global_var)

JavaScript 节点.js promise socket.io 回调

评论

0赞 Konrad 4/27/2023
这回答了你的问题吗?如何返回异步调用的响应?
0赞 User 4/28/2023
谢谢你的建议,但没有帮助我。正如您在我的演示中看到的,我还使用了 Promise()、.then / .catch() 子句和超时拒绝错误的计时器......

答: 暂无答案