【问题标题】:Why do my socket.on calls multiply whenever i recenter my controller为什么每当我重新定位我的控制器时,我的 socket.on 调用会成倍增加
【发布时间】:2014-01-08 21:41:33
【问题描述】:

我一直在使用这里由 brian ford 描述的套接字工厂 http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

这里是工厂 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);
                        }
                    });
                })
            }
        };
    });

我的控制器初始化函数中有一个 socket.emit,每当我从另一个页面重新进入这个控制器时,接收 socket.on 函数就会执行 +1 次。直到我手动刷新页面然后它重置为 1 才会发生这种情况。我没有明确地将我的套接字存储在会话中。那么是什么导致我的 socket.on 多次调用。

这是我的控制器中的 socket.emt 这总是执行一次。

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

这是我的 socket.on 将收到 'getSignedSlidesFromUrl'

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

这是我重新进入控制器后的控制台日志示例

即将从 init controllers.js:71 发出 getSignedSlidesFromUrl

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

如果我再次重新进入控制器,我的日志将变为

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 

【问题讨论】:

    标签: sockets angularjs socket.io


    【解决方案1】:

    您必须将 removeAllListeners 添加到您的工厂(见下文),并在每个控制器中包含以下代码:

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

    更新的套接字工厂:

     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);
                  });
              }); 
          }
        };
    });
    

    【讨论】:

    • 我添加了相同的代码,但仍然不影响代码。你能指导我吗?我在控制器中添加 $destory 并在套接字中添加新的 removeAllListeners() 方法。
    【解决方案2】:

    我尝试了@michaeljoser 的解决方案,但它对我不起作用。

    然后我找到了另一个解决方案,它起作用了

    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;
            }
        };
    });
    

    在控制器中,我调用了

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多