Socket.io client: respond to all events with a single handler?

Is it possible for the socket.io client to respond to all events without specifying each event separately?

For example, something like this (which is clearly not working right now):

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

I want this callback function to be called when all / all events have been received using socket.io code on the client side.

Is it possible? How?

+75
javascript events
May 01 '12 at 10:08 PM
source share
12 answers

It looks like the socket.io library stores them in a dictionary. Thus, do not think that it will be possible without changing the source.

From 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; }; 
+23
May 01 '12 at 10:18
source share

Updated solution for socket.io-client 1.3.7

 var onevent = socket.onevent; socket.onevent = function (packet) { var args = packet.data || []; onevent.call (this, packet); // original call packet.data = ["*"].concat(args); onevent.call(this, packet); // additional call to catch-all }; 

Use this:

 socket.on("*",function(event,data) { console.log(event); console.log(data); }); 

None of the answers worked for me, although one of Matthias Hopf and Maros Pixel came closer, this is my corrected version.

NOTE. , it only catches user events, and does not connect / disconnect, etc.

+72
Nov 27 '15 at
source share

Finally, there is a module called socket.io-wildcard that allows the use of wildcards on the client and server side

 var io = require('socket.io')(); var middleware = require('socketio-wildcard')(); io.use(middleware); io.on('connection', function(socket) { socket.on('*', function(){ /* … */ }); }); io.listen(8000); 
+18
May 11 '16 at 10:07
source share

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 capture events such as connecting , connect , disconnect , reconnecting , so be careful.

+11
Oct. 14 '12 at 17:41
source share

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

You can override the socket . $ emit

With the following code, you have two new features:

  • Trap of all events
  • Trap only events that are not captured by the old method (this is the 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)); }); 
+9
01 Oct '13 at 16:10
source share

The current (April 2013) GitHub document for open events mentions socket.on('anything') . It seems that “everything” is a placeholder for the name of the custom event, not the actual keyword that could catch any event.

I just started working with web sockets and Node.JS and immediately needed to process any event, as well as to find out which events were sent. I can not believe that this function is missing in socket.io.

+7
Apr 20 '13 at 11:53 on
source share

socket.io-client 1.7.3

As of May 2017, none of the other solutions could work the way I wanted - I made an interceptor using on Node.js only for testing purposes:

 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:

+5
May 16 '17 at 10:38 PM
source share

A lengthy discussion of this issue continues on the Socket.IO repository problem page. There are many solutions hosted there (for example, overriding EventEmitter with EventEmitter2). lmjabreu released another solution a couple of weeks ago: an npm module called socket.io-wildcard , which patnet in a substitution event on Socket.IO (works with the current Socket.IO, ~ 0.9.14).

+3
Jun 23 '13 at 8:30
source share

Since your question was quite general in asking for a solution, I will put it in, which does not require hacking the code, just a change in how you use the socket.

I just decided that my client application would send the 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 it can always use the same event, it can cause any problems, maybe some clashes on a scale, but it really helped my goals.

+3
May 27 '15 at 10:04
source share

All the methods that I found (including socket.io-wildcard and socketio-wildcard) did not work for me. Apparently, $ emit does not exist in socket.io 1.3.5 ...

After reading the socket.io code, I fixed the following with which the DID works:

 var Emitter = require('events').EventEmitter; var emit = Emitter.prototype.emit; [...] var onevent = socket.onevent; socket.onevent = function (packet) { var args = ["*"].concat (packet.data || []); onevent.call (this, packet); // original call emit.apply (this, args); // additional call to catch-all }; 

It may be a solution for others. However, at the ATM I don’t understand why someone else has no problems with the existing “solutions”?!? Any ideas? Maybe this is my old version of node (0.10.31) ...

+1
Apr 30 '15 at 1:04
source share

@ Reply by Matthias Hopf

Updated answer for v1.3.5. There was a bug with args if you want to listen to the old event and the * event together.

 var Emitter = require('events').EventEmitter; var emit = Emitter.prototype.emit; // [...] var onevent = socket.onevent; socket.onevent = function (packet) { var args = packet.data || []; onevent.call (this, packet); // original call emit.apply (this, ["*"].concat(args)); // additional call to catch-all }; 
+1
Jun 24 '15 at 15:15
source share

I am using Angular 6 and npm package: ngx-socket-io

 import { Socket } from "ngx-socket-io"; 

...

 constructor(private socket: Socket) { } 

...

After connecting the socket, I use this code, it processes all user events ...

 const onevent = this.socket.ioSocket.onevent; this.socket.ioSocket.onevent = function (packet: any) { const args = packet.data || []; onevent.call(this, packet); // original call packet.data = ["*"].concat(args); onevent.call(this, packet); // additional call to catch-all }; this.socket.on("*", (eventName: string, data: any) => { if (typeof data === 'object') { console.log('socket.io event: [${eventName}] -> data: [${JSON.stringify(data)}]'); } else { console.log('socket.io event: [${eventName}] -> data: [${data}]'); } }); 
0
Sep 21 '18 at 1:30
source share



All Articles