Wie kündige ich ein socket.io-Abonnement?

Lesezeit: 4 Minuten

Benutzer-Avatar
Bijou Trouvaille

Angenommen, es gibt Objekte, die einen Socket-Server wie folgt abonnieren:

socket.on('news', obj.socketEvent)

Diese Objekte haben eine kurze Lebensdauer und werden häufig erstellt, wodurch viele Abonnements generiert werden. Dies scheint ein Speicherleck und eine fehleranfällige Situation zu sein, die auf diese Weise intuitiv verhindert würde:

socket.off('news', obj.socketEvent)

bevor das Objekt gelöscht wird, aber leider gibt es keine off Methode im Socket. Gibt es eine andere Methode, die dafür gedacht ist?

Bearbeiten: Nachdem ich keine Antwort gefunden habe, weise ich eine leere Methode zu, um die Wrapper-Methode für den ursprünglichen Ereignishandler zu überschreiben, ein Beispiel folgt.

var _blank = function(){};

var cbProxy = function(){
    obj.socketEvent.apply(obj, arguments)
};
var cbProxyProxy = function(){
    cbProxy.apply ({}, arguments)
}
socket.on('news', cbProxyProxy);

// ...and to unsubscribe 
cbProxy = _blank;

Als ich mir die Quelle von socket.io.js ansah (konnte es nirgendwo in der Dokumentation finden), fand ich diese beiden Funktionen:

removeListener = function(name, fn)
removeAllListeners = function(name)

ich benutzte removeAllListeners erfolgreich in meiner App; aus diesen solltest du wählen können:

socket.removeListener("news", cbProxy);
socket.removeAllListeners("news");

Außerdem halte ich deine Lösung nicht für cbProxy = _blank würde tatsächlich funktionieren; das würde nur die betreffen cbProxy Variable, kein tatsächliches socket.io-Ereignis.

  • Das scheint zu funktionieren, das Ereignis verschwindet aus SocketNamespace, obwohl ich diesen Teil noch ausgiebig testen muss. Außerdem hatten Sie Recht mit der Proxy-Lösung, daher wurde sie aus Spaß aktualisiert

    – Bijou-Trouvaille

    14. März 2012 um 14:47 Uhr

  • Was funktioniert nicht? cbProxy war eine vom OP definierte Callback-Methode.

    – Andrew Magee

    11. August 2015 um 3:04 Uhr

Wenn Sie Listener erstellen möchten, die nur einmal “zuhört”, verwenden Sie socket.once('news',func). Socket.io wird den Listener automatisch zerstören, nachdem das Ereignis passiert ist – es heißt “volatile listener”.

Benutzer-Avatar
Pjotr

Wenn man sich den Code der aktuellen Version von Socket.io Client (1.4.8) ansieht, scheint es so aus, AlleListener entfernen, EventListener entfernen zeigen alle auf die gleiche Funktion.

Das Aufrufen einer davon, Angabe des Ereignisnamens und/oder Rückrufs, führt zum gewünschten Ergebnis. Nichts zur Verfügung zu stellen scheint alles zurückzusetzen.

Bitte seien Sie vorsichtig mit der fn/Rückruf Streit. Es muss dieselbe Instanz sein, die im Code verwendet wird.

Beispiel:

var eventCallback = function(data) {
  // do something nice
};
socket.off('eventName', eventCallback);

Würde wie erwartet funktionieren.

Beispiel (funktioniert auch):

function eventCallback(data) {
  // do something nice
}
socket.off('eventName', eventCallback);

Bitte seien Sie vorsichtig, dass der Rückruf, den Sie zu entfernen versuchen, derjenige ist, den Sie weitergegeben haben (dieser kann viel Verwirrung und Frustration stiften). Dieses Beispiel implementiert einen Wrapper um den anfänglichen Callback, der zu versuchen, ihn zu entfernen, würde nicht funktionieren, da der wirklich hinzugefügte Callback eine nicht offengelegte Abschlussinstanz ist: http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

Hier ist der Link zu dieser bestimmten Zeile in der Codebasis: https://github.com/socketio/socket.io-client/blob/master/socket.io.js#L1597

  • Diese Antwort benötigt mehr Upvotes, da die meisten anderen unvollständig und/oder extrem veraltet sind.

    – Anson Kao

    28. Oktober 2016 um 21:37 Uhr

  • Wenn Sie verwenden socket.io-client npm-Paket, dann funktioniert dies am besten, da removeAllListeners() ist parameterlos (also können Sie nicht angeben eventName).

    – Martin Schneider

    2. April 2018 um 13:48 Uhr

  • Weder der Rückruf von Off feuert, noch funktioniert das Off, wenn ein Rückruf gegeben wird.

    – Koushik Shom Choudhury

    9. Juni 2020 um 16:47 Uhr

  • Link zu den Dokumenten hier.

    – ViniciusArruda

    4. März 2021 um 17:06 Uhr

Socket.io Version 0.9.16 implementiert removeListener aber nicht off.

Sie können verwenden removeListener Anstatt von off bei der Abmeldung, oder einfach umsetzen off folgendermaßen:

  var socket = io.connect(url);
  socket.off = socket.removeListener;

Wenn Sie das Backbone verwenden listenTo Ereignisabonnement-Ansatz müssen Sie die oben genannten als Backbone-Aufrufe implementieren off beim Abbestellen von Veranstaltungen.

Ich habe festgestellt, dass in socket.io 0.9.11 und Chrome24 socket.io removeListener nicht funktioniert.

Diese modifizierte Version funktioniert bei mir:

EventEmitter.prototype.removeListener = function (name, fn) {
        if (this.$events && this.$events[name]) {
            var list = this.$events[name];

            if (io.util.isArray(list)) {
                var pos = -1;

                for (var i = 0, l = list.length; i < l; i++) {
                    if (list[i].toString() === fn.toString() || (list[i].listener && list[i].listener === fn)) {
                        pos = i;
                        break;
                    }
                }

                if (pos < 0) {
                    return this;
                }

                list.splice(pos, 1);

                if (!list.length) {
                    delete this.$events[name];
                }
            } else  {
                    if (list.toString() === fn.toString() || (list.listener && list.listener === fn)) {

                       delete this.$events[name];
                    }
            }
        }

        return this;
    };

Benutzer-Avatar
Josua Ohana

Da ich ein paar Probleme hatte, diese Arbeit zu machen, dachte ich, ich würde mich auch hier einklinken, zusammen mit einer netten aktualisierten Antwort für 2017. Danke an @Pjotr ​​für den Hinweis, dass es dieselbe Callback-Instanz sein muss.

Beispiel mit Angular2 TypeScript in einem socket-io.subscriber Dienst. Beachten Sie den Wrapper „newCallback“.

  private subscriptions: Array<{
    key: string,
    callback: Function
  }>;

  constructor() {
    this.subscriptions = [];
  }

  subscribe(key: string, callback: Function) {
    let newCallback = (response) => callback(response);
    this.socket.on(key, newCallback);
    return this.subscriptions.push({key: key, callback: newCallback}) - 1;
  }

  unsubscribe(i: number) {
    this.socket.removeListener(this.subscriptions[i].key, this.subscriptions[i].callback);
  }

Benutzer-Avatar
Jijo Paulose

Entfernen eines Ereignis-Listeners auf dem Client

var Socket = io.connect();
Socket.removeListener('test', test);

1051880cookie-checkWie kündige ich ein socket.io-Abonnement?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy