11

在 node 的幕后,http模块的createServer方法(及其回调)如何与事件循环交互?是否可以在用户空间中构建类似于createServer我自己的功能,或者这是否需要更改节点的底层系统代码?

也就是我对node的事件循环的大致理解是

  1. 事件循环滴答声
  2. Node 查找要运行的任何回调
  3. 节点运行这些回调
  4. 事件循环再次滴答作响,过程无限重复

我仍然有点模糊的是如何createServer适应事件循环。如果我做这样的事情

var http = require('http');

// create an http server  and handle with a simple hello world message
var server = http.createServer(function (request, response) {
    //...
});

我告诉节点在 HTTP 请求进入时运行我的回调。这似乎与我理解的事件循环模型不兼容。似乎有一些非用户态和非事件循环正在侦听 HTTP 请求,然后在有请求时运行我的回调。

换句话说——如果我考虑实现我自己的版本版本createServer,我想不出办法来做到这一点,因为我安排的任何回调都会运行一次。createServer只是使用setTimeout还是setInterval不断地重新检查传入的 HTTP 请求?或者是否有一些更低级别、更有效的事情发生。我知道我不需要完全理解这一点来编写高效的节点代码,但我很好奇底层系统是如何实现的。

(我尝试在节点源代码中跟随,但进展缓慢,因为我不熟悉节点模块系统,或者系统代码深处的编码模式的遗留假设)

4

2 回答 2

3

http.createServer是一种方便的方法,用于创建新http.Server()的回调并将回调作为事件侦听器附加到request事件。当然,node http 库也实现了协议解析。

没有对事件循环的持续轮询,节点正在等待 C++ tcp 绑定接收套接字上的数据,然后将这些数据编组buffer为您的回调。

如果您要实现自己的 http 解析器,您将从一个net.Server对象开始作为您的基础。在此处查看节点的实现:https ://github.com/joyent/node/blob/master/lib/_http_server.js#L253

于 2013-08-18T23:06:11.887 回答
1

正如 CrazyTrain 在评论中提到的,事件库生成和处理事件它有EventEmitter类,用于服务器、套接字和流等。

像您所说的事件循环在每次滴答后执行回调的无限循环。http 服务器提供的回调是一个事件处理程序,专门用于事件请求

var server = http.createServer(function (request, response) //request handler

事件处理程序可以执行多次。http.server是 EventEmitter 的一个实例。它处理传入请求的方式是它首先解析传入请求。解析时,它会发出请求事件。然后事件发射器使用提供的参数执行请求的回调。

你是对的,EventEmitter 不是事件循环的一部分。并且它需要由模块或库的开发者实现,只能使用模块用户提供的处理程序。但最重要的是,它提供了实现事件的必要机制。

于 2013-08-19T10:15:30.680 回答