Listen to all released events in Node.js

Is there a way in Node.js to listen to all events emitted by an EventEmitter?

for example, you can do something like ...

event_emitter.on('',function(event[, arg1][, arg2]...) {} 

The idea is that I want to capture all events that spit out on the server side of the EventEmitter , JSON.stringify data, send them through a connection to web servers, reorganize them on the client side as an event, and then act on the event on the client side .

+65
json javascript events
Mar 03 2018-11-11T00:
source share
13 answers

As already mentioned, this behavior is not in the core of node.js. But you can use hij1nx EventEmitter2:

https://github.com/hij1nx/EventEmitter2

It will not destroy existing code with EventEmitter, but will add support for namespaces and wildcards. For example:

 server.on('foo.*', function(value1, value2) { console.log(this.event, value1, value2); }); 
+38
Apr 04 2018-12-12T00:
source share

I know this is a little outdated, but what the hell is another solution you could take.

You can easily neutralize the emitting function of the emitter that you want to catch all the events:

 function patchEmitter(emitter, websocket) { var oldEmit = emitter.emit; emitter.emit = function() { var emitArgs = arguments; // serialize arguments in some way. ... // send them through the websocket received as a parameter ... oldEmit.apply(emitter, arguments); } } 

This is a fairly simple code and should work on any emitter.

+71
Aug 6 '13 at 17:47
source share

With ES6 classes, this is very simple:

 class Emitter extends require('events') { emit(type, ...args) { console.log(e + " emitted") super.emit(type, ...args) } } 
+15
Feb 29 '16 at 1:57
source share

Keep in mind that all of the solutions described above that might work will include some kind of hack into the internal implementation of Event.mitter for node.js.

The correct answer to this question will be as follows: EventEmitter implementation does not support this by default, you need to hack it .

If you look at the source code of node.js for an EventEmitter, you will see that when a listener is not connected to a certain type of event, it simply returns without any additional action, as it tries to extract the callback function from the hash. depending on the type of event:

https://github.com/nodejs/node/blob/98819dfa5853d7c8355d70aa1aa7783677c391e5/lib/events.js#L176-L179

This is why something like eventEmitter.on('*',()=>...) cannot work by default.

+6
Jan 30 '18 at 1:29
source share

The _events attribute seems to depend on listeners that are defined on the object, so it does not do what the question asks. In other words, if you define an e.on listener ("foo", ...), then "foo" appears in e._events, even if e never emits "foo". On the other hand, e may emit a “bar” which, if not listened to, will not be displayed in e._events.

For debugging, in particular, it would be nice to have such a “wildcard” feature, an e.on form listener ("*", ...), but this function does not seem to be available.

+1
Jun 14 2018-11-11T00:
source share

This is based on Martin's answer above. I'm a little new to node, so I needed to solve my answer for myself. The method at the end, logAllEmitterEvents is an important bit.

 var events = require('events'); var hungryAnimalEventEmitter = new events.EventEmitter(); function emitHungryAnimalEvents() { hungryAnimalEventEmitter.emit("HungryCat"); hungryAnimalEventEmitter.emit("HungryDog"); hungryAnimalEventEmitter.emit("Fed"); } var meow = function meow() { console.log('meow meow meow'); } hungryAnimalEventEmitter.on('HungryCat', meow); logAllEmitterEvents(hungryAnimalEventEmitter); emitHungryAnimalEvents(); function logAllEmitterEvents(eventEmitter) { var emitToLog = eventEmitter.emit; eventEmitter.emit = function () { var event = arguments[0]; console.log("event emitted: " + event); emitToLog.apply(eventEmitter, arguments); } } 
+1
Jan 26 '15 at 17:40
source share

I needed to keep track of all the emitted events in all libraries, so I connected to prototype .

This example uses Typescript signature , but you can just delete it if you aren’t in such nonsense.

As part of the call, this refers to the object that emits. It was very easy to track the entire unique object: throws it into my project.

  // For my example I use a 'set' to track unique emits. const items = new Set() const originalEmit = EventEmitter.prototype.emit; EventEmitter.prototype.emit = function (event: String | Symbol, ...args: any[]): boolean { // Do what you want here const id = this.constructor.name + ":" + event; if (!items.has(id)) { items.add(id); console.log(id); } // And then call the original return originalEmit.call(event, ...args); } 

You can very easily extend this and filter based on event name or class name.

+1
Nov 15 '18 at 3:23
source share

You might want to learn the RPC modules for node.js. If I'm not mistaken, the Dnode RPC module has a chat server / client example similar to what you are trying to do. That way you can either use your module or copy what they do.

In short, the example shows a server that, when connected, creates listeners for all server events from the connected client. It does this by simply iterating over the stored list of event names.

 var evNames = [ 'joined', 'said', 'parted' ]; con.on('ready', function () { evNames.forEach(function (name) { emitter.on(name, client[name]); }); emitter.emit('joined', client.name); }); 

This code is smart because it automatically calls a remote procedure call on the client associated with the event when the event is fired.

0
Mar 11 '11 at 13:33
source share

Faced the same problem today, here is the solution:

 Object.create(Object.assign({},EventEmitter.prototype, { _onAnyListeners:[], emit:function(...args){ //Emit event on every other server if(this._fireOnAny && typeof this._fireOnAny === 'function'){ this._fireOnAny.apply(this,args) } EventEmitter.prototype.emit.apply(this,args) }, _fireOnAny:function(...args){ this._onAnyListeners.forEach((listener)=>listener.apply(this,args)) }, onAny:function(func){ if(typeof func !== 'function'){ throw new Error('Invalid type'); } this._onAnyListeners.push(func); }, removeOnAny:function(func){ const index = this._onAnyListeners.indexOf(func); if(index === -1){ return; } this._onAnyListeners.splice(index,1); } })); 
0
Aug 24 '18 at 8:59
source share

Starting with Node.js v6.0.0, the new class syntax and the argument distribution operator are fully supported, therefore it is quite safe and fairly easy to implement the desired functionality using simple inheritance and method overrides:

 'use strict'; var EventEmitter = require('events'); class MyEmitter extends EventEmitter { emit(type, ...args) { super.emit('*', ...args); return super.emit(type, ...args) || super.emit('', ...args); } } 

This implementation is based on the fact that the original emit method returns true / false depending on whether the event was processed by some listener or not. Note that overriding includes a return , so we save this behavior for other consumers.

The idea here is to use the star event ( * ) to create handlers that run for each individual event (say, for logging purposes) and an empty event ( '' ) for the default value or to intercept the entire handler that runs if nothing happens. still catches this event.

We always call the star ( * ) event first, because in the case of error events without any handlers, the result is actually an exception. EventEmitter implementation for more details.

For example:

 var emitter = new MyEmitter(); emitter.on('foo', () => console.log('foo event triggered')); emitter.on('*', () => console.log('star event triggered')); emitter.on('', () => console.log('catch all event triggered')); emitter.emit('foo'); // Prints: // star event triggered // foo event triggered emitter.emit('bar'); // Prints: // star event triggered // catch all event triggered 

Finally, if an EventEmitter instance already exists, but you want to configure this particular instance for a new behavior, this can easily be done by correcting the method at run time as follows:

 emitter.emit = MyEmitter.prototype.emit; 
0
Jan 30 '19 at 1:04
source share

patch monkey add onAny method to EventEmitter.

It’s useful to be able to track only the events of one problem.

 var EventEmitter=require('events') var origemit=EventEmitter.prototype.emit; Object.assign( EventEmitter.prototype, { emit:function(){ if(this._onAnyListeners){ this._onAnyListeners.forEach((listener)=>listener.apply(this,arguments)) } return origemit.apply(this,arguments) }, onAny:function(func){ if(typeof func !== 'function'){ throw new Error('Invalid type'); } if(!this._onAnyListeners)this._onAnyListeners=[]; this._onAnyListeners.push(func); }, removeOnAny:function(func){ const index = this._onAnyListeners.indexOf(func); if(index === -1){ return; } this._onAnyListeners.splice(index,1); } }); // usage example //gzip.onAny(function(a){console.log(a)}) 
0
Jul 26 '19 at 11:54 on
source share

You can also use another event emitter implementation, for example https://github.com/ozantunca/DispatcherJS . The implementation will look like this:

 dispatcher.on('*', function () {}); 

DispatcherJS also supports namespaces and even dependencies to determine which calls will be called first.

-one
Jan 15 '15 at 0:03
source share

Here's a debugging tool inspired by Martin that answers ( https://stackoverflow.com/a/412618/ ). I just used this to find out what happens in a set of threads by writing all their events to the console. It works great. As Martin shows, the OP can use it by replacing the console.log () call with the websocket sender.

 function debug_emitter(emitter, name) { var orig_emit = emitter.emit; emitter.emit = function() { var emitArgs = arguments; console.log("emitter " + name + " " + util.inspect(emitArgs)); orig_emit.apply(emitter, arguments); } } 
-one
Feb 03 '17 at 4:51 on
source share



All Articles