简体   繁体   English

(响应错误的NodeJS +套接字IO)NodeJS在页面刷新时在套接字上多次写入数据

[英](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. 每次页面刷新时,NodeJS都会在套接字上多次写入数据。 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. 当我刷新页面时,由Node.js服务器写入套接字的次数增加了,在多页面刷新时,写入次数已固定为3。

Please check console output for this weird response. 请检查控制台输出以获取此奇怪的响应。 Please suggest on the same. 请提出相同的建议。

Below is my server.js code: 以下是我的server.js代码:

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: 下面是我使用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)

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: 您必须保存时间间隔的ID,然后在客户端断开连接后按以下方式清除它:

// 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). 您应该意识到,添加到JS引擎事件循环中的每个时间间隔将永远旋转(或至少直到关闭应用程序时为止)。 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: 如果您不想跟踪添加到循环中的每个间隔,则可以使用setTimeout() ,只需在处理程序的末尾对其进行“重置”即可:

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) (肯定可以做得更好,但是您应该明白这一点)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM