Vishrant Vishrant - 2 months ago 13
Node.js Question

(Improper Response NodeJS + Socket IO) NodeJS is writing data multiple times on socket on page refresh

NodeJS is writing data multiple times on socket on every page refresh. When I am refreshing the pages the count of writing into socket by nodejs server increases, on multiple page refresh writing count is getting fixed to three.

Please check console output for this weird response. Please suggest on the same.

Below is my

server.js
code:

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

var server = require('http').createServer(app);

app.use(express.static(path.join(__dirname, 'public')));

var routes = require('./routes/index');
app.use('/', routes);

io.on('connection', function (socket) {
console.log('User connected. Socket id %s', socket.id);

// below if condition is as per @mdziekon suggestion which solves
// problem of multiple emits at the same time

if(Object.keys(io.sockets.connected).length < 2) {
var intervalID = setInterval(function () {
console.log("written " + new Date());

var temp = Math.floor(Math.random() * (50 - 0 + 1)) + 0;
var pressure = Math.floor(Math.random() * (1000 - 0 + 1)) + 0;

io.sockets.emit('temperature', temp);
io.sockets.emit('pressure', pressure);
}, 2000);
}


socket.on('disconnect', function () {
console.log('User disconnected. %s. Socket id %s', socket.id);
});

});

http.listen(8082, function() {
console.log('Server is listening at 8082');
});

module.exports = app;


Below is my client side code using angular js:

app.factory('socket', ['$rootScope', function($rootScope) {
var socket = io.connect();

return {
on: function(eventName, callback){
socket.on(eventName, callback);
},
emit: function(eventName, data) {
socket.emit(eventName, data);
},
removeAllListeners: function (eventName, callback) {
socket.removeAllListeners(eventName, function() {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
}
};
}]);

app.controller('socket-controller', ['$scope', 'socket', function($scope, socket){

socket.on('temperature', function(temperature) {
console.log('temperature ' + temperature);
$scope.$apply(function(){
$scope.temperature = temperature;
});
});

socket.on('pressure', function(pressure) {
console.log('pressure ' + pressure);
$scope.$apply(function(){
$scope.pressure = pressure;
});
$scope.pressure = pressure;
});

$scope.$on('$destroy', function (event) {
socket.removeAllListeners();
});

}]);


Below is the console output:

// before page refresh i.e. initial page loading, [everything works fine]

Server is listening at 8082
User connected. Socket id /#GQMJ3Qa3ozyTYlIPAAAA
written Sat Sep 03 2016 14:51:04 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:51:06 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:51:08 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:51:20 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:51:22 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:51:24 GMT+0530 (India Standard Time)
.
.
.// after page refresh
.// page refreshed once [please note timing [seconds] in below console, its writing twice]
.
User disconnected. /#GQMJ3Qa3ozyTYlIPAAAA. Socket id %s
User connected. Socket id /#fEGCbvwqIZDeAxmoAAAB
written Sat Sep 03 2016 14:52:46 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:48 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:48 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:50 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:50 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:52 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:52:52 GMT+0530 (India Standard Time)
.
.
. // again page refreshed [please note now its writing three times]
. // and after this refresh its constantly writing three times only
.
User disconnected. /#fEGCbvwqIZDeAxmoAAAB. Socket id %s
written Sat Sep 03 2016 14:54:49 GMT+0530 (India Standard Time)
User connected. Socket id /#Wi7oHtdXpVg08Fo6AAAC
written Sat Sep 03 2016 14:54:49 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:51 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:51 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:51 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:53 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:53 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:53 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:55 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:55 GMT+0530 (India Standard Time)
written Sat Sep 03 2016 14:54:55 GMT+0530 (India Standard Time)

Answer

That's because you are not removing your interval handler on disconnection.

You have to save interval's ID, and then, upon client disconnection, clear it like this:

// onConnect
var intervalID = setInterval(function () { ... }

// onDisconnect
socket.on('disconnect', function () {
    clearInterval(intervalID);
    ... rest of the code ...
}

You should be aware, that every interval added to the event loop of JS engine will spin forever (or at least until you close your application). If you don't want to track every interval added to the loop, you could use setTimeout(), and just "reset" it at the end of your handler:

var setupTimeout = function () {
    setTimeout(function () {
        // Your handling code / function
        myHandler();

        // Setup next timeout
        setupTimeout();
    }, 1000);
};

(this could definitely be done better, but you should get the point)

Comments