Socket.io Client: respond to all events with one handler?

前端 未结 14 1880
时光取名叫无心
时光取名叫无心 2020-11-28 04:16

Is it possible to have a socket.io client respond to all events without to have specify each event individually?

For example, something like this (which obviously do

相关标签:
14条回答
  • 2020-11-28 04:41

    Here you go ...

    var socket = io.connect();
    var globalEvent = "*";
    socket.$emit = function (name) {
        if(!this.$events) return false;
        for(var i=0;i<2;++i){
            if(i==0 && name==globalEvent) continue;
            var args = Array.prototype.slice.call(arguments, 1-i);
            var handler = this.$events[i==0?name:globalEvent];
            if(!handler) handler = [];
            if ('function' == typeof handler) handler.apply(this, args);
            else if (io.util.isArray(handler)) {
                var listeners = handler.slice();
                for (var i=0, l=listeners.length; i<l; i++)
                    listeners[i].apply(this, args);
            } else return false;
        }
        return true;
    };
    socket.on(globalEvent,function(event){
        var args = Array.prototype.slice.call(arguments, 1);
        console.log("Global Event = "+event+"; Arguments = "+JSON.stringify(args));
    });
    

    This will catch events like connecting, connect, disconnect, reconnecting too, so do take care.

    0 讨论(0)
  • 2020-11-28 04:43

    As it is in v3.0 documentation:

    socket.onAny((event, ...args) => {
      console.log(`got ${event}`);
    });
    
    0 讨论(0)
  • 2020-11-28 04:49

    Note: this answer is only valid for socket.io 0.x

    You can override socket.$emit

    With the following code you have two new functions to:

    • Trap all events
    • Trap only events which are not trapped by the old method (it is a default listener)
    var original_$emit = socket.$emit;
    socket.$emit = function() {
        var args = Array.prototype.slice.call(arguments);
        original_$emit.apply(socket, ['*'].concat(args));
        if(!original_$emit.apply(socket, arguments)) {
            original_$emit.apply(socket, ['default'].concat(args));
        }
    }
    
    socket.on('default',function(event, data) {
        console.log('Event not trapped: ' + event + ' - data:' + JSON.stringify(data));
    });
    
    socket.on('*',function(event, data) {
        console.log('Event received: ' + event + ' - data:' + JSON.stringify(data));
    });
    
    0 讨论(0)
  • 2020-11-28 04:49

    Because your question was pretty general in asking for a solution, I'll pitch this one that requires no hacking the code, just a change in how you use the socket.

    I just decided to have my client app send the exact same event, but with a different payload.

    socket.emit("ev", { "name" : "miscEvent1"} );
    socket.emit("ev", { "name" : "miscEvent2"} );
    

    And on the server, something like...

    socket.on("ev", function(eventPayload) {
       myGenericHandler(eventPayload.name);
    });
    

    I don't know if always using the same event could cause any issues, maybe collisions of some kind at scale, but this served my purposes just fine.

    0 讨论(0)
  • 2020-11-28 04:54

    The current (Apr 2013) GitHub doc on exposed events mentions a socket.on('anything'). It appears that 'anything' is a placeholder for a custom event name, not an actual keyword that would catch any event.

    I've just started working with web sockets and Node.JS, and immediately had a need to handle any event, as well as to discover what events were sent. Can't quite believe this functionality is missing from socket.io.

    0 讨论(0)
  • 2020-11-28 04:55

    socket.io-client 1.7.3

    As of May 2017 couldn't make any of the other solutions work quite how i wanted - made an interceptor, using at Node.js for testing purposes only:

    var socket1 = require('socket.io-client')(socketUrl)
    socket1.on('connect', function () {
      console.log('socket1 did connect!')
      var oldOnevent = socket1.onevent
      socket1.onevent = function (packet) {
        if (packet.data) {
          console.log('>>>', {name: packet.data[0], payload: packet.data[1]})
        }
        oldOnevent.apply(socket1, arguments)
      }
    })
    

    References:

    • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
    • https://github.com/socketio/socket.io-client/blob/ff4cb3eed04a95c9725b8aaba8b64fa9fa1ca413/lib/socket.js#L257
    0 讨论(0)
提交回复
热议问题