解构/黑客NodeJs

Deconstructing/Hacking NodeJs

本文关键字:NodeJs 黑客 解构      更新时间:2023-09-26

我正试图理解Node的内部工作原理,并且我正处于一个我无法将Node(用js编写)如何挂钩/绑定到用C/c++编写的低级系统调用的地方。

当我写这段代码-

var http = require('http');
var server = http.createServer(function(req,res) { res.end('Hacking Node'); });
server.listen(8081);

服务器如何。listen监听只有操作系统可以访问的特定端口?其他功能也是如此。

迄今为止的旅程是这样的。

我检查了net.js和os.js文件。但看不出什么来。

我还深入研究了用C编写的进程文件- unix和windows版本。

最后,经过进一步的调查,点击Node.js文件

// https://github.com/joyent/node/tree/6cbfcdad46d733bb04332063727e304e449dc86b/src/node.js

有以下注释-

// This file is invoked by node::Load in src/node.cc, and responsible for
// bootstrapping the node.js core. Special caution is given to the performance
// of the startup process, so many dependencies are invoked lazily.

和节点。cc在第2708行加载这个Node.js文件。

// https://github.com/joyent/node/blob/6cbfcdad46d733bb04332063727e304e449dc86b/src/node.cc - line 2708

我就知道这么多了。谁能告诉我接下来会发生什么,帮我把这个谜题填好?

我很惊讶没有人提到libuv。这是一个示意图。(不是100%准确)。

              2 V8 compiler
             /             '
            /               '
   1 Your code              3 node.js core system libraries(net,fs,events)
                                       JavaScript
                                      ------------    
                                     V8 bindings(C++)
                                         / | '
                                        /  |  '
                              4 node.js platform code C/C++
                                  events   fs  net
                                        '  |  /
                                         ' | / 
                                          '|/
                                        runs on
                                     5 libuv C/C++
                               High Performance Event Loop
                                           |
                                        syscalls
                                           |
                                        6 Kernel

记住如何使用。tostring()并显示JS函数。这对V8绑定不起作用(显示[本机代码])。node.js平台(c++)函数有V8绑定。因为node提供事件和异步执行,所以在事件循环中所做的一切都在libuv上运行。一个展示libuv用法的旧博客。

libuv为你处理系统调用的调度,V8处理你的JS代码。

谢谢user568109。这真的帮助我得到了一个完整的画面,它不是一个单一的东西,而是js, V8, libuv,内核的组合。它还使我能够更深入地挖掘,直到一个已知的抽象点。

我想分享一些我一路上收集到的知识。(如果太微不足道,请原谅我的无知)

  1. 首先,作为一个在浏览器上使用js的人,坐在浏览器上已经实现的DOM API之上,我没有想到可以在V8之上创建一个新的API。User568109在[本机代码]上的位引导我到这里和这里。节点绑定是这个难题中最重要的一块。

虽然下面的js代码行看起来像js,但实际上它们是不同的。一个是纯粹的js->js调用,而第二个是通过底层绑定实现的。

//normal js
var x = require('http');
var s = x.createServer();
//native binding
var tty = process.binding('tty_wrap');
tty.guessHandleType();
  1. 绑定在c++中的原生实现,表面的javascript只是一个语法糖或底层c++部分的抽象。Nikhil Marathe的演讲——幻灯片在这里——帮助我们更好地理解了事情。

  2. 现在js和V8的胶水已经解开了,很明显,一旦我们到了C/c++级别,它就可以直接(如果需要)或通过libuv与其他本地内核库对话。Bert Belder的这次演讲帮助我们更详细地理解了libuv。

理解了这幅图,现在我可以理解当我看到下面的行时发生了什么。

var http = require('http');
var server = http.createServer(function(req,res) { res.end('Hacking Node'); });
server.listen(8081);