Прослушайте все испускаемые события в узле.js



В Узел.в JS есть ли способ, чтобы слушать все события, испускаемые объектом EventEmitter?



например, вы можете сделать что-то вроде...



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


идея заключается в том, что я хочу, чтобы захватить все события выплюнуть на стороне сервера EventEmitter,JSON.stringify данные события, отправить его через соединение websockets, реформировать их на стороне клиента как событие, а затем действовать на событие на стороне клиента.

661   10  

10 ответов:

Как уже упоминалось, это поведение не находится в узле.Яш ядра. Но вы можете использовать Hij1nx'S EventEmitter2:

https://github.com/hij1nx/EventEmitter2

Он не будет нарушать существующий код с помощью EventEmitter, но добавляет поддержку пространств имен и подстановочных знаков. Например:

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

Я знаю, что это немного старовато, но какого черта, вот еще одно решение, которое вы могли бы принять.

вы можете легко обезьяна-патч функцию испускания излучателя вы хотите поймать все события:

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

Это довольно простой код и должен работать на любой излучатель.

с классами ES6 это очень просто:

class Emitter extends require('events') {
    constructor() {
        super()
    }

    emit(e) {
        console.log(e + " emitted")
        super.emit(...arguments)
    }
}

имейте в виду, что все решения, описанные выше, которые могут работать, будут включать в себя какой-то взлом для узла.внутренняя реализация JS EventEmitter.

правильный ответ на этот вопрос будет: реализация EventEmitter по умолчанию не поддерживает, что.

Если вы посмотрите на узел.исходный код js для EventEmitter, вы увидите, что когда слушатель не прикреплен к определенному событию, он просто вернется без каких-либо дальнейших действий: https://github.com/nodejs/node/blob/master/lib/events.js#L125-L128

вот почему что-то вроде eventEmitter.on('*', ()=>...) не может работать по умолчанию.

атрибут _events, по-видимому, зависит от слушателей, которые определены на объекте, поэтому он не делает то, что задает вопрос. Другими словами, если определить слушателя e. on ("foo",...), то "foo "появляется в e._events, даже если e никогда на самом деле не испускает"foo". С другой стороны, e может испускать "бар", который, если его не слушать, не будет отображаться в e._events.

для отладки, в частности, было бы неплохо иметь такую" подстановочную " возможность, слушатель формы е.о("*",...), но эта функция, похоже, недоступна.

это основано на ответе, который Мартин предоставил выше. Я немного новичок в node, поэтому мне нужно было решить его ответ для себя. Метод в конце, logAllEmitterEvents является важным битом.

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

вы можете заглянуть в модули RPC для узла.js. Если я не ошибаюсь, модуль Dnode RPC имеет пример сервера/клиента чата похоже на то, что вы пытаетесь сделать. Таким образом, вы можете либо использовать их модуль, либо скопировать то, что они делают.

короче пример показывает сервер, который при подключении создает слушателям для всех событий сервера от подключенного клиента. Он делает это, просто повторяя сохраненный список событий имена.

var evNames = [ 'joined', 'said', 'parted' ];

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

этот код является умным, потому что он автоматически вызывает удаленный вызов процедуры на клиенте, связанном с событием, когда событие испускается.

столкнулся с той же проблемой сегодня, вот решение:

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

вы также можете использовать другую реализацию эмиттера событий, например https://github.com/ozantunca/DispatcherJS. реализация будет выглядеть так:

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

DispatcherJS также поддерживает пространства имен и даже зависимости, чтобы определить, какие обратные вызовы будут вызваны в первую очередь.

вот инструмент отладки, вдохновленный ответом Мартина (https://stackoverflow.com/a/18087021/1264797). я только что использовал это, чтобы выяснить, что происходит не так в наборе потоков, регистрируя все их события на консоли. Отлично работает. Как показывает Мартин, OP может использовать его, заменив консоль.вызов log () с отправителем websocket.

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

Comments

    Ничего не найдено.