在angular中使用$ location.path()时,Socket.io不会连接

时间:2013-07-21 21:41:34

标签: javascript angularjs socket.io

我只想在我的webapp的一个部分使用socket.io。我使用socket.io的set('authorization',fn)来握手当前上下文(express session和page-id)。这在我刷新当前页面时效果很好,但在路由由$ location.path(url)处理时则不行。

Socket.io代码(视图控制器):

.controller('ViewCtrl', function ($scope, $routeParams, $http, $location, socket) {
  socket.connect('', { query: 'id=' + $routeParams.id });
  socket.emit('msg', { data: 'key'}); //DEBUG
  socket.on('connect', function(){
    console.log('Socket connected');
  });
  socket.on('disconnect', function(){
    console.log('Socket disconnected');
  });
  ...

路由代码(主控制器,首页):

if (data.owner == "yes") $location.path('/view/' + $scope.id());

路由当然也是服务器端安全的。

Socket.io服务:

.factory('socket', function ($rootScope) {
  var disconnecting = false;
  var socket = {};
  return {
    connect: function(url, query){
      disconnecting = false;
      socket = io.connect(url, query);
    },
    on: function(eventName, callback){
      socket.on(eventName, function(){
        var args = arguments;
        if(!disconnecting){
          $rootScope.$apply(function(){
            callback.apply(socket, args);
          });
        }
        else {
          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);
          }
        });
      })
    },
    disconnect: function(){
      disconnecting = true;
      socket.disconnect();
    },
    socket: socket
  };
});

我也尝试过直接在控制器中使用socket.io(没有服务),结果相同。

控制台也没有出现任何错误。

一个解决方案是将socket.io用于整个应用程序,使用emits传递page-id等。但是,当我在这个“视图页面”只需要socket.io时,这似乎是一种浪费。

修改: 这是它出错的地方(不应该忽略这一点):

$scope.$on('$destroy', function (event) {
  // disconnect socket when leaving page
  socket.disconnect();
});

1 个答案:

答案 0 :(得分:3)

Socket.io无法以connect() - >的方式工作disconnect() - >连接()。

创建单页应用程序时,io始终位于命名空间中,并且不会从io.sockets中删除套接字。因此,在第二个connect()处不会创建新的套接字。

查看socket.io客户端库中的第93行:

if (options['force new connection'] || !io.sockets[uuri]) {
  socket = new io.Socket(options);
}

解决方案,添加'强制新连接':

var socket = io.connect('', { 'force new connection': true, query: 'id=' + $routeParams.id });

感谢shaunhusain指示我进行Chrome调试!

参考:https://github.com/LearnBoost/socket.io-client/issues/251