Socket.io: Add wildcard support for events

Created on 29 Jul 2011  ·  130Comments  ·  Source: socketio/socket.io

It would be great if you could use a wildcard to capture all events. For example:

client.on("*", function(data) {

}
enhancement

Most helpful comment

how it's going?
+1 for on("*", function () { for both client and server

All 130 comments

agreed.

EventEmitter2

+1
This would allow us to create filters and what not for all events.

  • another dependency
  • must be reflected at client side (code?)
  • should catchall be called before particular event? or in the order of definition? clarification needed
  • only sync behavior -- wouldn't it be better to introduce custom _async_ filters for events?

+1

only sync behavior -- wouldn't it be better to introduce custom async filters for events?
@dvv

I'm quite interested in this idea.

some of the EE2 choices are not what I would consider ideal but I +1 the general idea of this, even if only "*" is supported

truly catchall: manager.on("event", function(client, event, data) {} -- will also allow to reduce number of closures

i don't remember any resistance to just adding a catchall listener, the only debate I remember was whether or not we use "*" or if we go with another method name like .addGlobalListener()

+1
I too would need a way to intercept all events, and have the specific handler get a look at them, only once I'm done processing it. Mostly for logging purposes would this be needed. Socket.io logger currently only logs to the console, and in a very self righteous way.
dvv -s approach is really to my liking.
In fact maybe it would be a good idea to have us relay the event to any specific handler, and we just get all events, as described by dvv.

Please get this issue in motion :)
Would love to see this feature implemented.

Well, ok, I just added EE2 to a branch in my fork: https://github.com/einaros/socket.io/commit/2107ff00f3ddf2d781d3e3c3b7dfb1fc990f7ec5

The branch is at: https://github.com/einaros/socket.io/commits/ee2

Thoughts are most welcome.

if EE2 gets rid of the weird method names and adds .on('*') I'd +1 that

I'm a -1 on EE2

It adds more bloat to the code, we also need to support it on the client side. Which means we would have to ship a extra 11.8 KB library (minified ~3.5kb). But with the up coming mobile market I would like to save as much bytes as possible.

If this is really only about having a wildcard / catch all listeners.. Then this should be done by overriding the existing emit function that just does one extra call to a all listener. This would be like a 3 - 5 LOC change (excluding comments ;)). And should be hidden behind a preference lock as it influence performance. EventEmitting is a hot code path and should always be as optimal and fast as possible. Adding wildcards will degrade performance.

catch-all is definitely the more important part, it's easy enough to switch on the event after that if necessary

Don't really care about wildcard's, or EE2, but a way, to intercept all events is a must.

if EE2 ... adds .on('*') I'd +1 that

TJ you crazy bro...

server.on('foo.*', function(value1, value2) {
  console.log(this.event, value1, value2);
});

That's from the README of EE2. Naturally, the "foo." is optional.

if EE2 gets rid of the weird method names

I agree.

@pyrotechnick the EE2 .on('*') isnt a catch-all iirc

* is not catch-all in the sense that it blindly catches all events but it does effectively catch all events since the pattern * matches all channels.

It's inefficient; but it does work as expected.

I was mistaken. You're right...

{EventEmitter2} = require 'eventemitter2'

emitter = new EventEmitter2 wildcard: on

emitter.on '*', ->
  console.log @event, arguments...

emitter.emit 'foo'
emitter.emit 'foo.bar'
isabel:hydrogen pyrotechnick$ coffee test.coffee 
foo

I almost prefer this behaviour when it comes to wildcards though.

When I think about all of this wildcard/"namespaced" events stuff it kind of makes me sad; JavaScript already has a fantastic way to match patterns -- they live in // or are constructed with RegExp. Is this just too slow?

Can I +1 the importance of this again. I'd love to see this in an upcoming release.

That doesn't work because I still can't connect to the event. In my application the server doesn't know the name of the room from the client. So I want to be able to respond to all messages for any room and ideally find out the name of the room that the message was sent on.

Add regular expression support for events.. this way, ranges of verbs and nouns can be caught.

+1

+1

+1

+1

+1

I would be fond of a super global method wich handle everything

io.set('global_listener', function(namespace, event, args, emit){
// do something based on namespace event and arguments
// I can or not call emit() to call event listeners linked with that namespace and that event
});

io.set('global_authorization', function(namespace, handshakeData, callback){
// based on namespace and handshakeData accept or not the connection
});

I needed an emitter that supported catch-alls a. la. socket.on("*"), worked on the client, and was still light weight. So I took @visionmedia's emitter from UI Kit and extended it a bit. Perhaps it would be a decent fit for this. So, for what it's worth. I'll just leave this here: https://github.com/HenrikJoreteg/wildemitter

@HenrikJoreteg
We might add '*' out of the box to https://github.com/component/emitter.
Also, that emitter is going to power next socket.io. It includes an off shortcut to removeListener which is nice :D

oh, awesome!

+1

++

+1

+1

+1

+1

+=1

+1

+1

+1

+1

Has anyone worked towards this yet ? Any kind of trail ?

I have a _sort of_ solution that worked well enough for the purposes we needed it for, but its not a full blown wildcard solution... more like an implementation of '*'

https://github.com/Attorney-Fee/socket.io

+1

+1

+1

+1

+1

+1

I hate to leave a comment that doesn't contribute anything meaningful, but this has been requested for 2 years now, and everything constructive has already been said. So...

+1

This would be fairly easy to add in userland, I don't see the need of having it in the core codebase. If I can help with any hooks to make it easier to extend the event emitter functionality without too much monkey patching I'll gladly do so.

How would this be implemented in userland? All the solutions I've seen involve forking the codebase, and some folks have linked to different libraries altogether.

In my case I only need a plain and simple "catch absolutely everything in one function," but RegEx support doesn't seem (to a guy who hasn't looked at the source too closely) too difficult, and would certainly be incredibly useful. I use regular expressions in my Express.JS routes all the time; it would be nice to be able to do the same in socket.io.

The transport layer / protocol would stay unaltered. You would simply override 'emit' on both ends to not simply do a map lookup but a more comprehensive (regexp based) search.

Quick implementation suggestions:

  • Override on to maintain a special datastructure for the regular expressions when '*' is found in the event name
  • Override emit to first do the fast case (regular map lookup), then go through the '*' listeners and see if they match.

Obviously this doesn't require a fork. What I meant by hooks is that we can potentially find a solution to not require the monkey-patching, but considering those 2 are pretty simple methods I don't consider that a big problem.

Just out of curiosity, couldn't we just override the socket.Manager.prototype.onClientMessage from userland?

I did so and worked just fine, in node, no changes to socket.io module. Not very pretty and likely to break but at least you avoid forking.

https://gist.github.com/lmjabreu/5714985

Couldn't one simply add process.EventEmitter = require('eventemitter2').EventEmitter2 somewhere before socket.io is required? This seems to work for me...

Opening up the prototype is definitely not a userland fix. I understand not wanting to implement full regex support or anything but a simple socket.on('*') would go a long way.

This ticket is 2 years old now.

Are there any plans to address it, as its clearly a useful feature?

If the answer is no, I would like to fork and add it myself.
But I would prefer to do this only if its likely to get merged back upsteam.

Can any devs answer this please?

Agreed with almost all comments, fancy stuff can be more o less debatable, but a catch-all would be nice. Users can do it themselves, but a predefined procedure would be cleaner.

It's a shame this doesn't exist.

It does exist, see the link someone posted earlier
http://stackoverflow.com/questions/8832414/overriding-socket-ios-emit-and-on/8838225

Im using this, and it works great :)

+1

Do monkey patching to something simple like that seems, to me, something like a bad practice, however, I think that no big implementation should be used, something simple like Backbone.Events will be sufficient for most devs in this issue, I think. (although Backbone does not use "*", but "all" for the global event, passing in the event name that is originally called, which is just the best thing to do). (its just a suggestion, however) =)

Personally +1 to the RegExp way, it feels more Javascript and less console when compared with the "*" wildcard.

But like the latest voices, a catch-all function seems more suitable.

Not sure if this is actually a socket.io issue tho.

A frozen API to blame IMO.

:+1:

In case anyone reads this thread and is still looking for a way to use wildcard events on 0.9.x and 1.0.0: https://www.npmjs.org/package/socketio-wildcard

Wonderful @geoah !

@guille hehe, it ain't mine I just stumbled upon it. thanks for all you hard work btw ^_^

Whipped up a middleware for socket.io last night.

https://www.npmjs.org/package/socket.io-events

+1
It would be nice to cut the overhead of creating new listeners when the data will always be handled the same.
@geoah Thanks for the middleware, did exactly what I needed!

If the middleware works fine, then socket.io should stay as is.

This is one of those things that I personally feel makes perfect sense as part of socket.io itself. I see no argument for leaving it out except "that's not the way things are done around here", which is never a very good argument.

The argument is that we try to work just like the node EventEmitter, and node doesn't have this, so it would become a "socket.io-ism". There were extensive discussions in Node about adding it and it didn't make it through.

@chevex While this was originally my feeling as well, the new middleware support makes it pretty easy to add in yourself. Looking at socketio-wildcard as an example, it's dead simple to import and use; it'll probably just end up being like express.js where there's a couple pieces of middleware I almost always include.

Those are much better arguments. I guess you wouldn't want the EventEmitter to behave differently from node's by default. And @DanH42 I also suppose you're right that augmenting it with middleware makes more sense for those who need it. I retract my statement :)

If only node's EventEmitter supported wildcards out of the box.

:+1:

I see I missed this issues, I started a new issue on forwarding events:
https://github.com/Automattic/socket.io/issues/1715
It includes two ways to handle all events from socket.io 1.0 without altering it's source.

I just want this for debugging. I don't have the authoritah to add or modify libraries in our project. :sob:

+1
Sometimes, you need to know all the events that are propagating!

+1

  • 1

I ended up using hden's socketio-wildcard module; it seems the most transparent method (by using middleware) and works quite nicely for me. But :+1: for getting this into core!

Thanks Matt! I have been swamped but I hope to have a weekend to make some
improvements

Sent from my iPhone

On Jan 6, 2015, at 8:30 AM, Matt Fletcher [email protected] wrote:

I ended up using @NathanGRomano https://github.com/NathanGRomano's
socketio-events https://www.npmjs.com/package/socket.io-events module; it
seems the most transparent method (by using middleware) and works quite
nicely for me. But [image: :+1:] for getting this into core!


Reply to this email directly or view it on GitHub
https://github.com/Automattic/socket.io/issues/434#issuecomment-68864750.

+1

+1

++++++

+1 would be useful for debugging.

If it's a matter of someone just working on this, I'd like to give it a shot. I'll need some to learn the socket.io codebase, and I'll probably spend some time looking at other such implementations. What are your thoughts on regex patterns? Too slow? Of course, I'm not going to waste my time if it's not something that would be considered for a merge (I don't care if my implementation is rejected, but if there is no interest then why bother, right?). Will a maintainer please advise?

I wrote a library socket.io-events. I've been swamped with work and need
to touch it again. I'd like to support the acknowledgments with it

On Saturday, July 25, 2015, John Manko [email protected] wrote:

If it's a matter of someone just working on this, I'd like to give it a
shot. I'll need some to learn the socket.io codebase, and I'll probably
spend some time looking at other such implementations. What are your
thoughts on regex patterns? Too slow? Of course, I'm not going to waste my
time if it's not something that would be considered for a merge (I don't
care if my implementation is rejected, but if there is no interest then why
bother, right?). Will a maintainer please advise?


Reply to this email directly or view it on GitHub
https://github.com/socketio/socket.io/issues/434#issuecomment-124901706.

+1

+1 this issue is going on 5 years old. Why hasn't wildcard support been added in, again?

+1

+1

+1

+1

+666

+1

Guys, seriously. Everyone wants this feature- I think they get it. Let's all stop with the plus-ones, please? I'd rather get an update email when there's some actual progress with the issue.

That said, it's useful to know that many people are interested.
I think ideally GitHub should have a voting system?

A voting system would be great, but doesnt seem likely to happen anytime soon.

I guess the problem is a solution has been posted many times now, but scrolls out of view because of all the +1 comments.

The socketio-wildcard module has been working well for me (admittedly I haven't updated to latest node yet).
It would be useful if someone could explain why this lib is not suitable?

Yeah, socketio-wildcard works perfectly well, but it's still an extra dependency that is so simple that it would be nice to be introduced into core and just end this whole issue thread once and for all. Also it removes any room for confusion as to which is the best external module to use (often similarly named). Also agree that it would be good if GitHub had a voting system, if only there was a way we could vote on it...!

I may be dumb, but I have no clue how to set up socketio-wildcard with IO client objects. This should seriously, _seriously_ be included in the core. If socket.io's maintainers don't want to do it, someone should just fork this project and we could all move there, because this is just ridiculous and I have honestly have zero trust in socket.io now.

I understand that maintainers don't have to accept every proposal, but this? This just totally baffles me. Way to go.

@n2liquid it's not as clear that this should be in core, but the discussion is welcome. For example, no other Node event emitter behaves this way, even though a discussion was had there as well when.

@rauchg

it's not as clear that this should be in core, but the discussion is welcome

Could we have a discussion about this then?

I can understand your point that this sort of emitter is not necessarily common in the node world, but it depends what you are trying to achieve....
Is the idea to strictly adhere to conventions, or provide a really useful library?

It seems clear that many users of socket.io are really stumbling without this feature being in core, and it seems reasonable for a user to expect that it should be.

Or to put it another way, what are the arguments to NOT provide this feature in socket.io?
Even if the implementation is not 'textbook correct', it would result in a standard way to implement these 'catchall' handlers in socket.io, rather than people having to resort to lots of different libraries and methods.
Directing people to a third party lib or workaround only fragments things, and makes it even more fragile trying to maintain a codebase which uses socket.io

I would much rather there was a formal way to handle catchall packets, and then if it needs to be changed later, at least there can be a recommended migration procedure, rather than just leaving it for the user to find their own route through the wilderness

@rauchg I think a cool way to implement this would to have a socket.use(function(data,next){..}) function that catches all events on the socket, and is passed a next() function that passes control from the catchall to subsequent catchalls or default event handlers.

This is how I am using socket.io right now because I needed a way to limit the amount of events coming in per/minute, which I believe is a common use case. Thanks for reading my 2 cents.

I like @Michael77's solution the most. It doesn't touch the event emitter interfaces or implementation and even allows for more things than we're asking here (e.g. @Michael77's message throttling implementation and who knows what else).

I know there's a middleware / use function in socket.io, but it's not usable on the client library, and I'm not sure if it serves this same purpose.

@carpii there are always great reasons to _not_ support something: adding complexity, reducing familiarity. This feature checks off both.

I like the socket.use idea a lot, on top of which one could easily implement the wildcard extension on the client.

Thanks @carpii @Michael77 @n2liquid for your feedback on this btw.

@rauchg, I'm sorry I said those bad things about socket.io. I was having a bad day. Thank you for this project; it may not be perfect (yet), but it sure is very useful.

Also: https://github.com/hden/socketio-wildcard/issues/13

@n2liquid _all_ feedback is welcome – thank you (and to @hden for that quick fix on socket.io-wildcard).

scoketio-wildcard seems like a perfectly valid solution. I found myself also wanting to get the event name in callback, so that I could wrap the socket listener and propagate events through the wrapper, rather than directly exposing the socket to the rest of my application. My understanding is that this would require Event Emitter 2 if I wanted to do this with a wildcard. Is this just something silly to do, better to directly expose the socket? Something based on listening for 'newListener' in the wrapper (but don't know how to trigger on socket event, only how to register the socket event based on the calling functions registering a new event in the wrapper)? Anyone else interested in being able to access the event name within the callback?

@akotlar The event name is available in the callback if you are using scoketio-wildcard.

Ah, thanks! It may be useful to specify this in the socket.io-wildcard readme.

how it's going?
+1 for on("*", function () { for both client and server

+1 all the way

@alexey-sh @emin93 If you would kindly read the document from https://github.com/hden/socketio-wildcard, yes it's possible to do so for both client and server.

@hden Thanks and yes i saw that and i'm already using it. But it's an extra dependency and nothing speaks against integrating it directly into Socket.IO core, that's why it gets a +1 from me.

It can be handled in the app logic using one event name for all events:

socket.emit('public-event', {'type': 'login', ...});
socket.emit('public-event', {'type': 'logout', ...});

+1 even though issue is closed.

+💯 bang!

+1 !!!!

Please use socket.use.

Is there a way to hook into engine.io's PING/PONG mechanism using socket.use() ?

I am having an issue where many users are losing connection, and despite extensive logging on server, it just says they disconnected due to Ping Timeout.

I'd like to log the PING/PONG packets, but it seems socket.use() can only hook into the high level user-event messages, and not engine.io's underlying protocol

+1

+1

+1 since 2011? They ain't doing it. :(

Again, socket.use was added for that matter: https://socket.io/docs/server-api/#socket-use-fn

@darrachequesne I don't see how a method on the server-side helps with this request (which is for the client).

Any more on this? Since socket.use is only for the server, why is this ticket closed?

I don't understand socket.use. How to replace

// Server
io.in('room1').emit('backend', data_out);
io.in('room1').emit('frontend', data_out);

with something like

// Server
io.in('room1').emit('*end', data_out);  // not working code - proper regex would be nice

or

// Client
socket.on('*end', function(data){  // not working code - proper regex would be nice

Found a small workaround - listing all possibilities:

// Client
var lala = function(data){ 
    // example
}
socket.on('backend', lala);
socket.on('frontend', lala);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

varHarrie picture varHarrie  ·  3Comments

Elliot9 picture Elliot9  ·  4Comments

MichaelJCole picture MichaelJCole  ·  3Comments

stnwk picture stnwk  ·  4Comments

MyMomSaysIAmSpecial picture MyMomSaysIAmSpecial  ·  4Comments