在Angular.js视图上多次触发的Socket.io事件更改

时间:2015-10-15 18:36:36

标签: javascript angularjs sockets

警告:我对编码和网站开发很陌生。

我正在创建一个角度应用程序,它使用socket.io将节点(快速)服务器上的实时事件传递给其他客户端。我遇到的问题是,当我在应用程序中并切换来自" / pb"到" /"然后再回来," init"套接字事件在客户端被触发两次。据我所知,客户端正在发出" requestInit"事件只有一次,服务器通过发出" init"事件只有一次。但是,当我切换视图时,客户端多次在socketio.on(' init')函数中运行代码。

例如:我将打开应用程序并导航到/ pb,控制台将记录

connected to socket
recieved socket event from server: Init
initCount: 1 

现在当我导航到" /"然后回到" / pb",控制台将记录

recieved socket event from server: Init
initCount: 2
recieved socket event from server: Init
initCount: 1

每次切换视图时,initCount都会变高,所以如果我来回切换5次,initCount会记录5次,从5开始,以1结束。

因此,当我进入视图时,客户端的socketio.on(' init')函数被多次触发,并且按向后顺序触发。我最初的猜测是,当我切换视图时,套接字没有关闭,所以当我回来时,它会收到一个" init"每个打开的套接字的事件。但是,socketio.on(' connect')功能仅在初始导航到" / pb"时触发。我已经谷歌搜索了几个小时,我仍然无法找到最新情况。任何帮助,将不胜感激。这是给我带来麻烦的鳕鱼。

客户端:

var app = angular.module('MainApp', ['ngRoute']);

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider){

    $routeProvider
        .when('/', {
            templateUrl: 'views/home.html',
            controller: 'HomeController',
            activeTab: 'home'
        })
        .when('/pb', {
            templateUrl: 'views/pb.html',
            controller: 'PbController',
            activeTab: 'pb'
        })
        .otherwise({
            redirectTo: '/'
        });

    $locationProvider.html5Mode(true);
}]);

// SocketIO factory
app.factory('socketio', ['$rootScope', function($rootScope){
    var socket = io.connect('http://localhost:3000');
    return {
        on: function(eventName, callback){
            socket.on(eventName, function() {
                var args = arguments;
                $rootScope.$apply(function(){
                    callback.apply(socket, args);
                });
            });
        },
        emit: function(eventName, data, callback){
            socket.emit(eventName, data, function() {
                var args = arguments;
                $rootScope.$apply(function(){
                    if(callback){
                        callback.apply(socket, args);
                    }
                });
            });
        }
    };
}]);

app.controller('PbController', ['$scope', 'socketio', function ($scope, socketio){

     $scope.initCount = 0;
/*
    ~~~~~~~~~~ Socket events ~~~~~~~~~~~~~~~~
*/
    socketio.emit('requestInit');

    socketio.on('connect', function(){
        console.log('connected to socket');
    });

    socketio.on('init', function (){
        console.log("recieved socket event from server: Init");
        $scope.initCount += 1;
        console.log("init count: " + $scope.initCount);
    });
}]);

服务器:

var pbServerController = function (io){

io.on('connection', function (socket){
    console.log("Client connected, new socket issued: "+socket.id);

    socket.on('requestInit', function(){
        console.log("sending Init socketio event");
        socket.emit('init');
    });
};

module.exports = pbServerController;

2 个答案:

答案 0 :(得分:2)

不确定你是否想过这个。如果不是,您可以使用范围销毁套接字侦听器。

在您的控制器中:

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

答案 1 :(得分:0)

如果有人仍在努力解决此问题。我遇到了同样的问题,我通过在工厂外初始化套接字变量并在所有其他控制器上使用了该变量来解决了这个问题。

app = angular.module('movex', ['ui.router'])
socket = io.connect('http://localhost:3000');

我不知道这是不是正确的方法,但是它解决了问题。