我过去遇到过问题,其中SocketIO在使用AngularJS时会发出重复事件。出现这种情况的原因有两个常见原因:
connect
事件侦听器中创建事件侦听器。幸运的是,有两种常见的解决方案符合上述情况。请参阅接受的答案以了解这些解决方案。
答案 0 :(得分:0)
在connect
事件监听器
如果在connect
事件侦听器中创建侦听器,则会发生此错误。只需将这些侦听器移到connect
事件侦听器之外。
在:
socket.on('connection', _ => {
console.log('Connected');
socket.on('someOtherEvent', data => {
console.log(data);
});
});
后:
socket.on('connection', _ => {
console.log('Connected');
});
socket.on('someOtherEvent', data => {
console.log(data);
});
多次动态创建事件侦听器(通常使用AngularJS)。
如果在控制器中注册事件侦听器,这是一个常见问题。要解决此问题,请按以下方式编辑您的服务:
angular.module('socketIO', []).factory('socket', $rootScope => {
class SocketHandler {
constructor(url) {
this._socket = false;
this._url = url;
this._events = {};
this._build();
}
_build() {
// Change for your configuration options below.
this._socket = io.connect(this._URL);
}
on(event, callback) {
if(this._events.hasOwnProperty(event))
return this._events[event];
return this._events[event] = this._socket.on(event, (...args) => {
$rootScope.$apply(_ => {
callback.apply(this._socket, args);
});
});
}
emit(event, data, callback = false) {
return this._socket.emit(event, data, (...args) => {
if(!callback)
return;
$rootScope.$apply(_ => {
callback.apply(this._socket, args);
});
});
}
}
return { build: SocketHandler };
});
然后,您可以在构造函数中使用它:
angular.module('someController', socketIO => {
const socket = socketIO.build('your socket url');
});
此修复工作原因是因为当您在AngularJS(使用默认路由器)中切换页面时,它会重新创建控制器的实例。这意味着多个事件侦听器现在绑定到单个事件。我们通过在SocketHandler._events
中缓存我们的事件侦听器来阻止这种情况发生,并在缓存后返回缓存的侦听器。