简体   繁体   English

节点JS,createServer和事件循环

[英]Node JS, createServer, and the Event Loop

Behind the scenes in node, how does the http module's createServer method (and its callback) interact with the event loop? 在节点的幕后, http模块的createServer方法(及其回调)如何与事件循环交互? Is it possible to build functionality similar to createServer on my own in userland, or would this require a change to node's underlying system code? 是否有可能在我自己的用户区中构建类似于createServer功能,或者这需要更改节点的基础系统代码?

That is, my general understanding of node's event loop is 也就是说,我对节点的事件循环的一般理解是

  1. Event loop ticks 事件循环滴答声
  2. Node looks for any callbacks to run 节点查找要运行的任何回调
  3. Node runs those callbacks 节点运行这些回调
  4. Event loops ticks again, process repeats ad-infinitum 事件循环再次滴答作响,流程无限重复

What I'm still a little fuzzy on is how createServer fits into the event loop. 我仍然有点不createServercreateServer如何适合事件循环。 If I do something like this 如果我做这样的事情

var http = require('http');

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

I'm telling node to run my callback whenever an HTTP request comes in. That doesn't seem compatible with the event loop model I understand. 我告诉节点每当有HTTP请求进入时都运行我的回调。这似乎与我理解的事件循环模型不兼容。 It seems like there's some non-userland and non-event loop that's listening for HTTP requests, and then running my callback if one comes in. 似乎有一些非用户和非事件的循环正在侦听HTTP请求,然后在出现回调时运行我的回调。

Put another way — if I think about implementing my own version version of createServer , I can't think of a way to do it since any callback I schedule will run once. 换句话说,如果我考虑实现自己的createServer版本,则我想不出任何办法,因为我计划的任何回调都将运行一次。 Does createServer just use setTimeout or setInterval to constantly recheck for an incoming HTTP request? createServer是否仅使用setTimeoutsetInterval来不断地重新检查传入的HTTP请求? Or is there something lower level, more efficient going on. 还是存在更低级别,更高效的流程。 I understand I don't need to fully understand this to write efficient node code, but I'm curious how the underlying system was implemented. 我知道我不需要完全理解这一点即可编写高效的节点代码,但是我很好奇底层系统是如何实现的。

(I tried following along in the node source , but the going is slow since I'm not familiar with the node module system, or the legacy assumptions w/r/t to coding patterns deep in the system code) (我尝试在节点源中进行跟踪,但是由于我不熟悉节点模块系统,或者对系统代码深处的编码模式不加传统的假设,所以运行缓慢)

http.createServer is a convenience method for creating a new http.Server() and attaching the callback as an event listener to the request event. http.createServer是创建新的http.Server()并将回调作为事件侦听器附加到request事件的便捷方法。 Of course the node http library implements the protocol parsing, as well. 当然,节点http库也实现了协议解析。

There is no constant polling of the event loop, node is waiting for the C++ tcp bindings to receive data on the socket, which then marshall that data as a buffer to your callback. 事件循环没有持续的轮询,节点正在等待C ++ tcp绑定在套接字上接收数据,然后套接字将该数据编组为回调的buffer

If you were to implement your own http parser, you would start with a net.Server object as your base. 如果要实现自己的http解析器,则将从net.Server对象作为基础开始。 See node's implementation here: https://github.com/joyent/node/blob/master/lib/_http_server.js#L253 在此处查看节点的实现: https : //github.com/joyent/node/blob/master/lib/_http_server.js#L253

The events library does the generation and handling of events as mentioned by CrazyTrain in comments. 事件库负责CrazyTrain在评论中提到的事件的生成和处理。 It has EventEmitter class which is used for servers, sockets and streams etc. 它具有EventEmitter类,用于服务器,套接字和流等。

Event-loop like you said an infinite loop executing the callbacks after every tick. 像您说的事件循环一样,每个滴答之后都会执行一个无限循环来执行回调。 The callback provided with the http server is an eventhandler, specifically for event request . http服务器随附的回调是一个事件处理程序,专门用于事件请求

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

Eventhandlers can be executed multiple times. 事件处理程序可以执行多次。 http.server is an instance of EventEmitter . http.serverEventEmitter的一个实例。 The way it works incoming requests is that it first parses an incoming request. 它处理传入请求的方式是首先解析传入请求。 When parsed, it emits the request event. 解析后,它发出 请求事件。 The eventemitter then executes the callback for request with the parameters supplied. 然后,事件发射器使用提供的参数执行回调以进行请求。

You are right that EventEmitter is not a part of event loop. 没错,EventEmitter不是事件循环的一部分。 And it needs to be implemented by the developer of the module or library, only using the handlers provided by user of the module. 它仅需由模块或库的开发人员使用模块用户提供的处理程序来实现。 But most importantly, it provides the necessary mechanism to implement events. 但最重要的是,它提供了实现事件的必要机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM