周末在家磨磨唧唧了一上午,原因是作为一个学渣还在不停的逼迫自己痛苦的啃食编程书籍,读书的时候也是被动学习,如今工作了,稀里糊涂进入这一行,发现有很多自我否定的瞬间,也不知道这些年我是怎么过来的,依然还在这条路上且慢且行。好吧,既然已经做出了选择,那就把啃书打码变成一种习惯吧。接下里记录一下死月这本书的总结。
第一章 Node.js的c++扩展前驱知识储备
第一章
1、模块机制
common.js模块规范
- require
- 模块上下文
- 模块标识
- 未指定的约定
//math.js
exports.add=()=>{
var sum=0,i=0, args=arguments,1=args.length;
while(i<1){
sum+=args[i++];
}
return sum
}
//increments.js
let add=require('math').add;
exports.increment=(val)=>{
return add(val, 1);
}
//program.js
let inc=require('increment').increment;
let a=1;
inc(a);//2
module.id=='program'
2、包机制
包格式
common.js包的格式是一个包含整个包目录
目录结构:
- package.json在根目录下
- 二进制文件应当在bin目录下
- javascript源码在lib目录下
- 文档应该在doc目录下
- 单元测试文件应当在test目录下
CNPM
工作原理:将一些包缓存在node_modules/.npminstall目录下,再以符号链接(Symbol Link)的形式将依赖目录连接到其对应的路径。这样相同版本的包在安装过程中实际上只要一份实体。
3、依赖
chromeV8
V8会编译、执行js代码,一样会管理内存,垃圾回收等,V8高性能以及跨平台等特性
高效的4个特性
- JIT编译:即时编译
- 垃圾回收:JAVA VM的精确垃圾回收管理
- 内联缓存:确定属性偏移量,提高属性访问效率
- 隐藏类:对一个对象增加和修改属性的功能
V8为nodejs做的事情:
1、在chrome开发者工具中调试node.js
2、加速ES6
3、针对Node.js vm模块和REPL的一些修复
4、Async/await
libuv
nodejs的事件循环驱动
亮点特性:
- 基于epoll/kqueue/IOCP/event ports实现的全能事件循环
- 异步TCP和UDP套接字
- 异步DNS解析
- 异步文件、文件系统操作
- 文件系统事件
- ANSI转义码控制的TTY
- 使用UNIX domain套接字或者命名管道实现的套接字共享IPC;
- 子进程
- 线程池
- 信号处理
- 高精度时钟
- 线程和同步元
其他依赖
1、http-parser
能解析http协议的请求数据和返回数据
特性如下:
- 无依赖
- 持久化连接的流式处理keep-alive
- 分段信息chunk的解码
- 缓冲区溢出攻击的防御
该依赖主要解析HTTP消息中下面的一些内容:
1、消息头键值对header
2、内容长度Content-Length
3、请求方法(GET、POST、PUT DELETE等)
4、返回状态吗status code
5、传输编码(Transfer-Encoding)
6、HTTP版本;
7、请求地址(URL)
8、消息体
2、OpenSSL
安全套接字层协议库
SSL就是Secure Socket Layer的缩写,其可以在网络上提供秘密性传输。SSL包含记录层(Record Layer)和传输层,记录层协议确定传输层数据的封装格式。传输层安全协议使用X.509认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密钥作为会谈密钥。
3、Zlib 提供数据压缩功能的库
4、c++开发的环境准备
编辑器vs code
node-gyp:Python2.7 c++
- node-gyp build
- node-gyp clean
- node-gyp configure
- node-gyp rebuild
- node-gyp list
- node-type remove
第二章
使用c++来写Nodejs原生扩展的两大理由
性能更好,开发成本低,但是维护成本比较高,所以Nodejs只选择了一部分使用c++写法
c++扩展本质
在Nodejs中引入一个C++模块的过程,实际上就是Node.js在运行时引入了一个动态链接库的过程
几种模块的加载过程
1、C++核心模块
通过NODE_MODULE_CONTEXT_AWARE_BUILTIN等宏将不同的模块注册进Node.js C++核心模块链表中
2、Nodejs内置模块
会在Nodejs编译时被写入C++源码中并被编译到Node.js可执行二进制文件中,并在恰当的时机被拿出来闭包化导出
3、用户源码模块
会在首次执行require的时候被读取源码并闭包化导出,然后再加入模块缓存中
4、C++扩展
会在首次执行require时候通过uv_dlopen加载该扩展的*.node动态链接库文件,在链接库内部把模块注册函数赋值给modpending,然后将执行reuqire时传入的module和exports两个对象传入模块注册函数进行导出
[TOC]