问题描述
我目前正在使用 socket.io
来发出和侦听客户端 JavaScript 文件和 Node.js 服务器文件之间的事件,但我希望能够发出和侦听侦听 Node 服务器及其模块之间的事件.我的想法是它看起来像这样:
I'm currently using socket.io
to emit and listen to events between a client-side JavaScript file and a Node.js server file, but I'd like to be able to emit and listen to events between the Node server and its modules. My thought is that it would look something like this:
节点服务器:
var module1 = require('./module1');
//Some code to launch and run the server
module1.emit('eventToModule');
module1.emit('moduleResponse', function(moduleVariable) {
//server action based on module response
}
模块文件:
var server = require('./server.js');
server.on('eventToModule', function() {
//module response to server request
}
server.emit('moduleResponse', moduleVariable);
这显然是一个简化版本,但我认为应该可以使用此功能.我是否需要将模块文件设置为第二台服务器?如果是这样,那会是什么样子?
This is obviously a simplified version but I would think that this functionality should be available. Do I need to set up the module file as a second server? If so, what would that look like?
我也尝试使用 var socket = io.connect('http://localhost:3000');
(这是我用来允许客户端连接到 Node 服务器的代码)而不是 server
并让 module1
监听并发送到 socket
但这也不起作用.
I also tried using var socket = io.connect('http://localhost:3000');
(this is the code I use to allow the client to connect to the Node server) instead of server
and had module1
listen on and emit to socket
but that didn't work either.
第二次尝试(仍然无效):
SECOND ATTEMPT (still not working):
server.js
//other requirements
var module1 = require('./module');
const EventEmitter = require('events');
var emitter = new EventEmitter();
io.on('connection', function(client) {
client.on('emitterTester', function() {
emitter.emit('toModule');
emitter.on('toServer', function() {
console.log("Emitter successful.");
});
});
});
module.exports = emitter;
module.js
var server1 = require('./server');
const EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('toModule', function() {
console.log("Emitter heard by module.");
emitter.emit('toServer');
});
module.exports = emitter;
此外,当我尝试使用 server1.on
时,我收到消息 server1.on is not a function
.
Also, when I try to use server1.on
, I get the message server1.on is not a function
.
推荐答案
在 node.js 中,EventEmitter
对象 通常是您要创建具有事件侦听器然后可以触发事件的对象时使用的对象.您可以直接使用 EventEmitter
对象,也可以从中派生并创建您自己的具有所有 EventEmitter
功能的对象.
In node.js, the EventEmitter
object is typically what you use if you want to create an object that has event listeners and can then trigger events. You can either use the EventEmitter
object directly or you can derive from it and create your own object that has all the EventEmitter
functionality.
因此,如果您想创建一个其他模块可以侦听事件的模块,您可以这样做:
So, if you wanted to create a module that other modules could listen for events on, you would do something like this:
// module1.js
// module that has events
// create EventEmitter object
var obj = new EventEmitter();
// export the EventEmitter object so others can use it
module.exports = obj;
// other code in the module that does something to trigger events
// this is just one example using a timer
setInterval(function() {
obj.emit("someEvent", someData);
}, 10 * 1000);
然后,您可以使用另一个模块来使用第一个模块并侦听来自它的一些事件:
Then, you could have another module that uses that first one and listens for some events coming from it:
// module2.js
var m1 = require('module1.js');
// register event listener
m1.on("someEvent", function(data) {
// process data when someEvent occurs
});
这里的关键点是:
- 如果您想要一个模块允许人们监听事件然后触发事件,您可能需要创建一个
EventEmitter
对象. - 要共享该
EventEmitter
对象,您可以将其分配给module.exports
或module.exports
的属性,以便其他代码执行模块的require()
可以访问EventEmitter
对象. - 一旦调用代码从
require()
获取了EventEmitter
对象,它就可以注册以使用.on()
监听事件代码>方法. - 当原始模块或任何模块想要触发事件时,它可以使用
.emit()
方法来实现.
- If you want a module to allow people to listen for events and to then trigger events, you probably want to create an
EventEmitter
object. - To share that
EventEmitter
object, you assign it tomodule.exports
or a property ofmodule.exports
so that other code that does arequire()
of your module can get access to theEventEmitter
object. - Once the calling code gets the
EventEmitter
object from therequire()
, it can then register to listen for events with the.on()
method. - When the original module or any module wants to trigger an event, it can do so with the
.emit()
method.
请记住,有时事件是一个很好的架构选择,但并非模块之间的所有通信都最适合事件.有时,只导出函数并允许一个模块调用另一个模块的函数是有意义的.因此,事件并不是模块相互通信的唯一方式.
Keep in mind that sometimes events are a great architectural choice, but not all communication between modules is best suited to events. Sometimes, it makes sense to just export functions and allow one module to call another module's functions. So, events are not the only way that modules can communicate with one another.
您的问题似乎表明您认为 socket.io 是同一服务器进程中的两个模块进行通信的一种方式.虽然有可能这样做,但这通常不是 socket.io 的使用方式.通常 socket.io(基于 TCP/IP)将用于两个独立进程之间的通信,在这些进程中,您无法进行直接函数调用或为进程内的事件注册处理程序.后两种方案通常更容易在进程内进行通信,而 socket.io 更通常用于同一台计算机上的进程之间或不同计算机上的进程之间的通信.
Your question seems to indicate that you think of socket.io as a way for two modules in the same server process to communicate. While it might be possible to do that, that is not normally how socket.io would be used. Usually socket.io (which is TCP/IP based) would be used for communicating between two separate processes where you do not have the luxury of making a direct function call or registering a handler for an event within your process. These latter two schemes are typically much easier for communication within a process, whereas socket.io is more typically use for communication between processes on the same computer or between processes on different computers.
这篇关于如何在带有 Node.js 的 JavaScript 模块文件之间使用事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!