86 votes

Client Socket.io : répondre à tous les événements avec un seul gestionnaire ?

Est-il possible d'avoir un client socket.io qui répond à tous les événements sans avoir à spécifier chaque événement individuellement ?

Par exemple, quelque chose comme ceci (qui ne fonctionne évidemment pas pour l'instant) :

var socket = io.connect("http://myserver");

socket.on("*", function(){
  // listen to any and all events that are emitted from the
  // socket.io back-end server, and handle them here.

  // is this possible? how can i do this?
});

Je veux que cette fonction de rappel soit appelée lorsqu'un ou plusieurs événements sont reçus par le code socket.io côté client.

Est-ce possible ? Comment ?

0 votes

J'ai ouvert le problème suivant sur le transfert de tous les types d'événements, j'ai également ajouté les solutions que j'ai trouvées : github.com/Automattic/socket.io/issues/1715

25voto

lukiffer Points 4944

Il semble que la bibliothèque socket.io les stocke dans un dictionnaire. En tant que tel, je ne pense pas que cela soit possible sans modifier la source.

De source :

EventEmitter.prototype.on = function (name, fn) {
    if (!this.$events) {
      this.$events = {};
    }

    if (!this.$events[name]) {
      this.$events[name] = fn;
    } else if (io.util.isArray(this.$events[name])) {
      this.$events[name].push(fn);
    } else {
      this.$events[name] = [this.$events[name], fn];
    }

    return this;
  };

3 votes

J'ai aussi trouvé ceci : stackoverflow.com/questions/8832414/

0 votes

En 2019, je ne pense pas que ce soit encore le cas.

11voto

Kaustubh Karkare Points 780

Voilà...

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));
});

Cela permettra d'attraper des événements tels que connecting , connect , disconnect , reconnecting aussi, alors faites attention.

0 votes

Socket.IO.js build:0.9.10, développement.

3 votes

Est-ce que ça a fini dans un communiqué ?

9voto

leszek.hanusz Points 1285

Note : cette réponse n'est valable que pour socket.io 0.x

Vous pouvez passer outre socket.$emit

Avec le code suivant, vous disposez de deux nouvelles fonctions :

  • Piéger tous les événements
  • Trappe uniquement les événements qui ne sont pas trappés par l'ancienne méthode (il s'agit d'un listener par défaut)

    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 votes

Tout conseil sur une opération d'aync avant d'appeler apply. setTimeout(function() { original_$emit.apply(socket, ['*'].concat(args)) ; if(!original_$emit.apply(socket, arguments)) { original_$emit.apply(socket, ['default'].concat(args)) ; } } ; 2000 }, 2000) ;

0 votes

J'utilise Socket.IO 1.3.6 et il semble qu'il n'y ait pas de méthode $emit dans le fichier socket plus

0 votes

En effet. Consultez la réponse de @Flion pour les versions 1.x.

7voto

Dan Dascalescu Points 8165

Le courant (avril 2013) Document GitHub sur les événements exposés mentionne un socket.on('anything') . Il semble que "n'importe quoi" soit un espace réservé pour un nom d'événement personnalisé, et non un mot-clé réel qui permettrait d'attraper n'importe quel événement.

Je viens de commencer à travailler avec les sockets web et Node.JS, et j'ai immédiatement eu besoin de gérer n'importe quel événement, ainsi que de découvrir quels événements ont été envoyés. Je n'arrive pas à croire que cette fonctionnalité est absente de socket.io.

3voto

vote539 Points 973

Hay une longue discussion sur ce sujet en cours sur la page des problèmes du dépôt Socket.IO. Diverses solutions y sont proposées (par exemple, remplacer EventEmitter par EventEmitter2). lmjabreu a publié une autre solution il y a quelques semaines : un module npm appelé socket.io-wildcard qui ajoute un événement joker à Socket.IO (fonctionne avec la version actuelle de Socket.IO, ~0.9.14).

4 votes

Mais cela ne concerne que le serveur... son module n'est pas utilisable du côté client (navigateur).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X