Node.js에서 발신된 모든 이벤트 듣기
Node.js에서는 EventEmitter 객체에 의해 발신된 모든 이벤트를 리슨하는 방법이 있습니까?
예를 들어, 다음과 같은 것을 할 수 있습니까?
event_emitter.on('',function(event[, arg1][, arg2]...) {}
를 모두 입니다.EventEmitter,JSON.stringify이벤트 데이터를 웹소켓 연결을 통해 전송하고 클라이언트 측에서 이벤트로 재구성한 다음 클라이언트 측에서 이벤트를 처리합니다.
이게 좀 오래된 건 알지만, 대체, 여기 당신이 취할 수 있는 다른 해결책이 있어요.
모든 이벤트를 포착하는 이미터의 이미트 함수를 쉽게 원숭이로 패치할 수 있습니다.
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);
}
}
이것은 매우 간단한 코드이며, 모든 이미터에서 동작합니다.
전술한 바와 같이 이 동작은 node.js core에는 없습니다.그러나 hij1nx의 EventEmitter2를 사용할 수 있습니다.
https://github.com/hij1nx/EventEmitter2
EventEmitter를 사용하여 기존 코드를 해제하지 않지만 네임스페이스와 와일드카드 지원이 추가됩니다.예를 들어 다음과 같습니다.
server.on('foo.*', function(value1, value2) {
console.log(this.event, value1, value2);
});
ES6 클래스에서는 매우 간단합니다.
class Emitter extends require('events') {
emit(type, ...args) {
console.log(type + " emitted")
super.emit(type, ...args)
}
}
위에서 설명한 모든 솔루션에는 node.js EventEmitter 내부 구현에 대한 일종의 해킹이 수반된다는 점에 유의하십시오.
이 질문에 대한 정답은 기본 EventEmitter 구현은 이를 지원하지 않으므로 이를 회피해야 합니다.
EventEmitter의 node.js 소스 코드를 보면 청취자가 이벤트유형을 키로 사용하여 해시에서 취득된 것을 알 수 있습니다.키를 찾을 수 없는 경우 추가 액션 없이 반환됩니다.
https://github.com/nodejs/node/blob/98819dfa5853d7c8355d70aa1aa7783677c391e5/lib/events.js#L176-L179
그런 게...eventEmitter.on('*', ()=>...)디폴트로는 동작할 수 없습니다.
Node.js v6.0.0 입니다.class구문 및 인수 확산 연산자가 완전히 지원되므로 간단한 상속과 메서드 덮어쓰기를 통해 원하는 기능을 구현하는 것이 매우 안전하고 쉽습니다.
'use strict';
var EventEmitter = require('events');
class MyEmitter extends EventEmitter {
emit(type, ...args) {
super.emit('*', ...args);
return super.emit(type, ...args) || super.emit('', ...args);
}
}
에서는, 의 「」, 「PC」, 「PC」, 「PC」가, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「PC」, 「」, 「」,emit의 of의 EventEmittertrue/false이벤트가 일부 청취자에 의해 처리되었는지 여부에 따라 달라집니다.에는 「」가 포함되어 있는 것에 해 주세요.return다른 소비자를 위해 이 동작을 유지합니다.
서는 별자리 이벤트 이벤트)를 입니다.*를 들어 로깅을 및빈예를 들어, " " " ( " " " " ( " " " " " " ) " 을 합니다.''디폴트 핸들러 또는 catch all 핸들러의 경우 해당 이벤트가 검출되지 않으면 실행됩니다.
.*하도록 하겠습니다.왜냐하면error핸들러가 없는 이벤트에서는 실제로는 예외가 느려집니다.상세한 것에 대하여는, 의 실장을 참조해 주세요.
예를 들어 다음과 같습니다.
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
마지막으로 EventEmitter 인스턴스가 이미 존재하지만 특정 인스턴스를 새로운 동작에 맞게 조정하려면 다음과 같이 실행 시 메서드에 패치를 적용하면 됩니다.
emitter.emit = MyEmitter.prototype.emit;
이것은 Martin이 위에서 제시한 답변에 근거하고 있습니다.저는 노드를 처음 접하기 때문에 제가 직접 그의 답을 알아내야 했습니다.마지막 메서드 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);
}
}
라이브러리에서 한 모든 에 "Manager"를 .prototype.
에서는, 「」를 하고 있습니다.Typescript signature하지만 그런 허튼소리에 관심이 없다면 그냥 없애버리면 된다.
에서는, 「」this는 방출되는 물체를 나타냅니다.프로젝트의 모든 독특한 오브젝트, 즉 에밋을 추적하는 것은 매우 쉬웠습니다.
// 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);
}
이벤트 이름 또는 클래스 이름을 기준으로 필터링 및 확장을 매우 쉽게 수행할 수 있습니다.
monkey patch add on Event Emitter에 임의의 메서드를 추가합니다.
한 가지 문제의 이벤트만 감시할 수 있으면 편리합니다.
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)})
node.js의 RPC 모듈을 조사하는 것이 좋습니다.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);
}
}));
다음은 Martin의 답변에서 영감을 얻은 디버깅 도구입니다(https://stackoverflow.com/a/18087021/1264797)).이 기능을 사용하여 스트림의 모든 이벤트를 콘솔에 기록함으로써 스트림 집합에서 무엇이 잘못되었는지 알아냈습니다.효과가 좋다.Martin이 설명한 바와 같이 OP는 console.log() 콜을 웹 소켓 송신기로 대체하여 사용할 수 있습니다.
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);
}
}
https://github.com/ozantunca/DispatcherJS 등의 다른 이벤트 이미터 구현도 사용할 수 있습니다.실장은 다음과 같습니다.
dispatcher.on('*', function () {});
디스패처또한 JS는 네임스페이스 및 의존관계도 지원하여 어떤 콜백을 먼저 호출할지를 결정합니다.
언급URL : https://stackoverflow.com/questions/5178869/listen-to-all-emitted-events-in-node-js
'source' 카테고리의 다른 글
| 컨트롤러에서 AngularJS 모달 대화 상자 양식 개체가 정의되지 않았습니다. (0) | 2023.04.02 |
|---|---|
| BigQuery 테이블의 스키마를 JSON으로 내보낼 수 있는 방법이 있습니까? (0) | 2023.04.02 |
| PHP가 JSON을 JQUERY AJAX 호출로 반환 (0) | 2023.03.28 |
| JSON 스키마에 선언된 속성만 허용 (0) | 2023.03.28 |
| AngularJS 및 ng-grid - 셀 변경 후 데이터를 서버에 자동 저장 (0) | 2023.03.28 |