Open
Description
net.Server
net.Server
构造函数用于创建TCP,IPC服务。是http.Server
等的基类。
基础
事件
1. connection
事件:
当新建立连接(比如TCP握手完成后)时触发,创建新的net.Socket
对象。
2. listening
服务已经绑定好了,正在监听连接请求。除了显示的绑定listening
事件外,调用listen
方法传入的callback也是会被绑定为listening
处理函数(一次性绑定)。
3. ...
属性
1. listening
表示当前服务是否正在监听连接,
ObjectDefineProperty(Server.prototype, 'listening', {
__proto__: null,
get: function() {
return !!this._handle; // 服务器句柄的计算值
},
configurable: true,
enumerable: true
});
2. this._handle
服务器句柄,用于监听连接
listen
方法
listen
方法可谓是net.Server
最核心的方法。调用该方法让服务监听连接请求(看着很简短但是逻辑却不简单)。
listen
做了哪些事情?
以建立TCP服务(不考虑cluster)为例看看listen
做了哪些事情。
- 创建服务器句柄(serverHandle), 即对
this._handle
属性赋值;
this._handle
对象是为了让nodejs调用底层libuv库创建的socket而进行的封装,即是net.Server
实例和底层socket联系的桥梁。
setupListenHandle
代码片段
function setupListenHandle(address, port, addressType, backlog, fd, flags) {
...
if (rval === null)
rval = createServerHandle(address, port, addressType, fd, flags);
if (typeof rval === 'number') {
const error = uvExceptionWithHostPort(rval, 'listen', address, port);
process.nextTick(emitErrorNT, this, error);
return;
}
this._handle = rval;
...
// 额外赋值,这样底层收到连接请求时可以调用onconnection回调
this[async_id_symbol] = getNewAsyncId(this._handle);
this._handle.onconnection = onconnection;
this._handle[owner_symbol] = this;
// 调用底层的listen开始监听端口
const err = this._handle.listen(backlog || 511);
...
defaultTriggerAsyncIdScope(this[async_id_symbol],
process.nextTick,
emitListeningNT, // 触发`listening`事件
this);
}
- 绑定地址和端口;
- 触发
listening
事件。
进阶
调用onconnection
函数
node在C++层调用js层的onconnection
函数,并传入底层的socket,完成�底层socket与node net模块的连接与请求打通。
onconnection
函数内部主要做了两件事:
- 构建nodejs层的
net.Socket
对象; - 并触发
connection
事件。
function onconnection(err, clientHandle) {
const handle = this;
const self = handle[owner_symbol];
...
const socket = new Socket({
handle: clientHandle,
allowHalfOpen: self.allowHalfOpen,
pauseOnCreate: self.pauseOnConnect,
readable: true,
writable: true
});
...
self._connections++; // 记录已建立的连接数量
socket.server = self; // 额外赋值,即可以通过socket反向获取服务对象
socket._server = self;
self.emit('connection', socket);
...
}