Why do my socket.on calls multiply whenever i recenter my controller

耗尽温柔 提交于 2020-01-02 15:25:13

问题


I've been using the socket factory described here by the brian ford here http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

here is the factory myApp.factory('socket', function ($rootScope) {

     var socket = io.connect('url');
        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);
                        }
                    });
                })
            }
        };
    });

I have a socket.emit in my controllers initialization function and whenever i reenter this controller from another page the receiving socket.on function executes +1 times. This happens until I manually refresh the page then it resets to 1. I don't explicitly store my socket in session. So what could be causing my socket.on to call multiple times.

Here is my socket.emt in my controller this always executes once.

$scope.init = funciton (){
...
socket.emit('getSignedSlidesFromUrl', $scope.slideLocation);
}

Here is my socket.on that will be recieve 'getSignedSlidesFromUrl'

socket.on('signedUrls', function (signedSlides){
            console.log('signedUrls socket hit');
            $scope.slides = signedSlides;
            console.log($scope.slides[0]);
            console.log($scope.display);
        });

Here is an example of my console log after reentering the controller

about to emit getSignedSlidesFromUrl from init controllers.js:71

display after called $scope.first slide is0 controllers.js:574
flash object is controllers.js:537
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823

if I reenter the controller again my log would change to

signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823 

回答1:


You have to add removeAllListeners to your factory (see below) and have the following code in each of your controllers:

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

Updated socket factory:

 var socket = io.connect('url');
    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);
                    }
                });
            })
        },
      removeAllListeners: function (eventName, callback) {
          socket.removeAllListeners(eventName, function() {
              var args = arguments;
              $rootScope.$apply(function () {
                callback.apply(socket, args);
              });
          }); 
      }
    };
});



回答2:


I tried @michaeljoser's solution, but it didn't work for me.

Then I found another solution and it worked

var socket = io.connect('url');
    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);
                    }
                });
            })
        },
        getSocket: function(){ 
            return socket;
        }
    };
});

And in controller, I called

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


来源:https://stackoverflow.com/questions/21007164/why-do-my-socket-on-calls-multiply-whenever-i-recenter-my-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!