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

Socket.io does not connect when using $location.path() in angular

本文关键字:Socket 不连接 io path angular location      更新时间:2023-09-26

我只想在我的网络应用程序的一个部分使用socket.io。我使用socket.io的集合("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通信页面id等。但当我只需要socket.io时,这似乎是一种浪费。

编辑:这就是它出错的地方(不应该忽略这一点):

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

Socket.io不以connect()->disconnect()->connect(。

当创建一个单页应用程序时,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