AngularJSを使用しているときにSocketIOが重複イベントを発生させるという問題が発生しました。これがなぜ発生するのかという一般的な理由は2つあります。AngularJSとのSocketIO重複イベント
connect
イベントリスナー内にイベントリスナーを作成する。- イベントリスナーは複数回動的に作成されます(通常、AngularJSの場合)。
幸いにも、上記のシナリオに一致する2つの共通の解決策があります。これらの解決策を理解するには、受け入れられた回答を参照してください。
AngularJSを使用しているときにSocketIOが重複イベントを発生させるという問題が発生しました。これがなぜ発生するのかという一般的な理由は2つあります。AngularJSとのSocketIO重複イベント
connect
イベントリスナー内にイベントリスナーを作成する。幸いにも、上記のシナリオに一致する2つの共通の解決策があります。これらの解決策を理解するには、受け入れられた回答を参照してください。
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 };
});
次に、あなたのコンストラクタでこれを使用することができます
:デフォルトで(AngularJSでページを切り替えるときので、この修正プログラムが動作します
angular.module('someController', socketIO => {
const socket = socketIO.build('your socket url');
});
理由がありますルータ)は、コントローラのインスタンスを再作成します。つまり、複数のイベントリスナーが1つのイベントにバインドされています。これは、イベントリスナーをSocketHandler._events
にキャッシングし、キャッシングされている場合はキャッシュされたリスナーを返すことで発生しません。