Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wildcard support for events #434

Closed
edmellum opened this issue Jul 29, 2011 · 132 comments
Closed

Add wildcard support for events #434

edmellum opened this issue Jul 29, 2011 · 132 comments
Labels
enhancement New feature or request

Comments

@edmellum
Copy link

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

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

}
@joshrtay
Copy link

joshrtay commented Aug 5, 2011

agreed.

EventEmitter2

@DennisRas
Copy link

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

@dvv
Copy link
Contributor

dvv commented Aug 17, 2011

  • 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?

@525c1e21-bd67-4735-ac99-b4b0e5262290

+1

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

I'm quite interested in this idea.

@tj
Copy link
Contributor

tj commented Oct 3, 2011

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

@dvv
Copy link
Contributor

dvv commented Oct 4, 2011

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

@mikeal
Copy link

mikeal commented Oct 4, 2011

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()

@hdf
Copy link

hdf commented Oct 9, 2011

+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.

@DennisRas
Copy link

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

@einaros
Copy link
Contributor

einaros commented Oct 9, 2011

Well, ok, I just added EE2 to a branch in my fork: einaros@2107ff0

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

Thoughts are most welcome.

@tj
Copy link
Contributor

tj commented Oct 9, 2011

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

@3rd-Eden
Copy link
Contributor

3rd-Eden commented Oct 9, 2011

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.

@tj
Copy link
Contributor

tj commented Oct 9, 2011

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

@hdf
Copy link

hdf commented Oct 9, 2011

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

@525c1e21-bd67-4735-ac99-b4b0e5262290

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.

@tj
Copy link
Contributor

tj commented Oct 9, 2011

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

@525c1e21-bd67-4735-ac99-b4b0e5262290

* 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.

@525c1e21-bd67-4735-ac99-b4b0e5262290

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?

@jrperina
Copy link

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

@ghost
Copy link

ghost commented Jan 26, 2012

@jrperina
Copy link

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.

@mycall
Copy link

mycall commented Feb 5, 2012

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

@ivzhao
Copy link

ivzhao commented Mar 1, 2012

+1

4 similar comments
@mikermcneil
Copy link

+1

@tapanpandita
Copy link

+1

@alberteddu
Copy link

+1

@jcrugzz
Copy link

jcrugzz commented Jul 12, 2012

+1

@dmail
Copy link

dmail commented Jul 31, 2012

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

@HenrikJoreteg
Copy link

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

@rauchg
Copy link
Contributor

rauchg commented Aug 27, 2012

@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

@guiprav
Copy link

guiprav commented Dec 25, 2015

@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: hden/socketio-wildcard#13

@rauchg
Copy link
Contributor

rauchg commented Dec 25, 2015

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

@akotlar
Copy link

akotlar commented Jan 22, 2016

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?

@hden
Copy link

hden commented Jan 22, 2016

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

@akotlar
Copy link

akotlar commented Jan 22, 2016

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

@alexey-sh
Copy link

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

@emin93
Copy link

emin93 commented Apr 16, 2016

+1 all the way

@hden
Copy link

hden commented Apr 17, 2016

@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.

@emin93
Copy link

emin93 commented Apr 18, 2016

@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.

@mkhahani
Copy link

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', ...});

@juanpaulo
Copy link

+1 even though issue is closed.

@crobinson42
Copy link

+💯 bang!

@materazu
Copy link

+1 !!!!

@darrachequesne
Copy link
Member

Please use socket.use.

@carpii
Copy link

carpii commented Dec 17, 2016

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

@freeman3s
Copy link

+1

1 similar comment
@gtk2k
Copy link

gtk2k commented Feb 13, 2018

+1

@bolajipemipo
Copy link

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

@darrachequesne
Copy link
Member

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

@ghost
Copy link

ghost commented May 15, 2019

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

@pecknigel
Copy link

pecknigel commented Aug 8, 2019

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

@bor8
Copy link

bor8 commented Jun 30, 2020

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

@darrachequesne darrachequesne mentioned this issue Oct 23, 2020
9 tasks
darrachequesne added a commit that referenced this issue Oct 25, 2020
Inspired from EventEmitter2 [1]

```js
io.on("connect", socket => {

  socket.onAny((event, ...args) => {});

  socket.prependAny((event, ...args) => {});

  socket.offAny(); // remove all listeners

  socket.offAny(listener);

  const listeners = socket.listenersAny();
});
```

Breaking change: the socket.use() method is removed

This method was introduced in [2] for the same feature (having a
catch-all listener), but there were two issues:

- the API is not very user-friendly, since the user has to know the structure of the packet argument
- it uses an ERROR packet, which is reserved for Namespace authentication issues (see [3])

[1]: https://github.com/EventEmitter2/EventEmitter2
[2]: #434
[3]: https://github.com/socketio/socket.io-protocol
@numandev1
Copy link

can i use subscribe like this socket.on('posting/*'
where I wanna get all posting like this
posting/1
posting/2
posting/3

@darrachequesne
Copy link
Member

@nomi9995 no, but implementing this should be quite straightforward:

socket.onAny((eventName, ...args) => {
  if (/posting\/.*/.test(eventName)) {
    // ...
  }
});

Reference: https://socket.io/docs/v4/listening-to-events/#socketonanylistener

dzad pushed a commit to dzad/socket.io that referenced this issue May 29, 2023
Inspired from EventEmitter2 [1]

```js
io.on("connect", socket => {

  socket.onAny((event, ...args) => {});

  socket.prependAny((event, ...args) => {});

  socket.offAny(); // remove all listeners

  socket.offAny(listener);

  const listeners = socket.listenersAny();
});
```

Breaking change: the socket.use() method is removed

This method was introduced in [2] for the same feature (having a
catch-all listener), but there were two issues:

- the API is not very user-friendly, since the user has to know the structure of the packet argument
- it uses an ERROR packet, which is reserved for Namespace authentication issues (see [3])

[1]: https://github.com/EventEmitter2/EventEmitter2
[2]: socketio#434
[3]: https://github.com/socketio/socket.io-protocol
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests