How to unsubscribe from a socket.io subscription?

前端 未结 11 1318
长发绾君心
长发绾君心 2020-11-30 02:00

Suppose there are objects making subscriptions to a socket server like so:

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

These objects have a short life

相关标签:
11条回答
  • 2020-11-30 02:01

    To add to @Andrew Magee, here is an example of unsubscribing socket.io events in Angular JS, and of course works with Vanilla JS:

    function handleCarStarted ( data ) { // Do stuff }
    function handleCarStopped ( data ) { // Do stuff }
    

    Listen for events:

    var io = $window.io(); // Probably put this in a factory, not controller instantiation
    io.on('car.started', handleCarStarted);
    io.on('car.stopped', handleCarStopped);
    
    
    $scope.$on('$destroy', function () {
        io.removeListener('car.started', handleCarStarted);
        io.removeListener('car.stopped', handleCarStopped);
    });
    
    0 讨论(0)
  • 2020-11-30 02:02

    If you want to create listeners that "listens" only once use socket.once('news',func). Socket.io automatically will distroy the listener after the event happened - it's called "volatile listener".

    0 讨论(0)
  • 2020-11-30 02:02

    Also on java client, it can be done the same way with the Javascript client. I've pasted from socket.io.

    // remove all listeners of the connect event
    socket.off(Socket.EVENT_CONNECT);
    
    listener = new Emitter.Listener() { ... };
    socket.on(Socket.EVENT_CONNECT, listener);
    // remove the specified listener
    socket.off(Socket.EVENT_CONNECT, listener);
    
    0 讨论(0)
  • 2020-11-30 02:04

    I found that in socket.io 0.9.11 and Chrome24 socket.io removeListener doesn't work.

    this modified version works for me:

    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;
        };
    
    0 讨论(0)
  • 2020-11-30 02:07

    This has helped me in both Angular 8 and React 16.8:

    receiveMessage() {
        let newCallback = (data) => {            
            this.eventEmitter.emit('add-message-response', data);
        };
        this.socket.on('add-message-response', newCallback);
    
        this.subscriptions.push({key: 'add-message-response', callback: newCallback});
    }
    
    receiveMessageRemoveSocketListener() {
        this.findAndRemoveSocketEventListener('add-message-response');
    }
    
    findAndRemoveSocketEventListener (eventKey) {
        let foundListener = this.subscriptions.find( (subscription) => subscription.key === eventKey );
    
        if(!foundListener) {
          return;
        } 
    
        this.socket.removeListener(foundListener.key, foundListener.callback);
        this.subscriptions = this.subscriptions.filter( (subscription) => subscription.key !== eventKey );
    }
    

    Reason for using an Array of Subscriptions is that when you Subscribe to an event multiple times and you don't remove an unsubscribed subscription from the Subscription list you will most probably be right at first time you remove the subscription from the list, but later subscriptions will not be removed as you will be finding first instance only every time you unsubscribe the event.

    You can simply call receiveMessage(); to subscribe to an the event and receiveMessageRemoveSocketListener(); to Unsubscribe.

    0 讨论(0)
  • 2020-11-30 02:13

    Pre-store the events using an array, and by the time you need to unsubscribe them, use the off method, which is a built in method from socket.io:

    // init
    var events = []
    
    // store
    events.push("eventName")
    // subscribe
    socket.on("eventName", cb)
    
    // remove
    events = events.filter(event => event!="eventName")
    // unsubscribe
    socket.off("eventName")
    
    0 讨论(0)
提交回复
热议问题