I want to emit 5 events message, in a loop, using socket.io and node.js.
This is what I’ve tried so far:
HTML client
//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>
Node.JS server:
//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}`);
});
On server console, I’ve got follow debug messages:
---------- 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
As you can see, server messages are good, but on client side, I’ve received something like that:
I don’t know why, but all 5 responses are with first value ‘1’…I can’t received all values from 1 to 5.
I expected from server something like this, after every emit event from server to see a message with right value and at the end in browser console, after all 5 loops are over, to display:
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
After that I need those values outside Promise callback to assign them to another global variable (global_var)