浅析node ws@1.1.5(中-客户端篇)

本文详细探讨了ws库中WebSocket客户端的工作原理,包括open和message事件的触发机制,以及response、upgrade和data事件的相关分析。还提到了NODE_DEBUG环境变量用于调试源码,并提供了关键代码片段和时序图以帮助理解整个流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇主要分析ws的客户端。时序图在页末,不想看代码的直接翻到底部就可以了
var WebSocket = require('ws');
var ws = new WebSocket('ws://127.0.0.1:19999');
ws.on('open', function open() {
   
   
  ws.send(...);
});
ws.on('message', function message(data, flags) {
   
   
	...
});

上面是文档给的示例, 所以这次研究的是 open\color{green}{open}openmessage\color{green}{message}message 事件何时被调用。

var WS = module.exports = require('./lib/WebSocket');
function WebSocket(address, protocols, options) {
   
   
	initAsClient.apply(this, [address, protocols, options]);
}

function initAsClient(address, protocols, options) {
   
   
  	....省略 requestOptions 初始化部分
  	var req = httpObj.request(requestOptions);
	req.once('response', function response(res) {
   
   
		// 关闭连接
	    cleanupWebsocketResources.call(self, error);
	});
	
	req.once('upgrade', function upgrade(res, socket, upgradeHead) {
   
   
		...
	    establishConnection.call(self, Receiver, Sender, socket, upgradeHead);
	});
	req.end();
}

function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) {
   
   
  var ultron = this._ultron = new Ultron(socket), called = false, self = this;
    // 连接永不超时
  socket.setTimeout(0);
  this._receiver = new ReceiverClass(this.extensions,this.maxPayload);
  this._socket = socket;
  function firstHandler(data) {
   
   
    socket.removeListener('data', firstHandler);
    ultron.on('data', realHandler);
    if (data) realHandler(data);
  }
  function realHandler(data) {
   
   
    self._receiver.add(data);
  }
  ultron.on('data', firstHandler);
  process.nextTick(firstHandler);
  self._receiver.ontext = function ontext(data, flags) {
   
   self.emit('message', data, flags);};

  self._receiver.onbinary = function onbinary(data, flags) {
   
   self.emit('message', data, flags);};
  
  this._sender = new SenderClass(socket, this.extensions);
  this.emit('open');
}

上述代码, open\color{green}{open}open 事件 由 upgrade\color{green}{upgrade}upgrade 事件 触发。 message\color{green}{message}message 事件 没有看到触发代码, 但是相关代码有 self._receiver.ontext。 同时又暴露了几个问题:

  1. response\color{green}{response}response 事件 一旦被触发, 说明连接会被强制关闭。 那什么情况会被触发这个事件
  2. upgrade\color{green}{upgrade}upgrade 事件 何时会触发
  3. ultron 的 data\color{green}{data}data 事件 何时触发

提供一个debug命令,这样就可以打印一些内部的注释信息, 帮助阅读源码

export NODE_DEBUG=*

这个是 requestOptions
{ port: ‘19999’,
host: ‘127.0.0.1’,
headers:
{ Connection: ‘Upgrade’,
Upgrade: ‘websocket’,
Host: ‘127.0.0.1:19999’,
‘Sec-WebSocket-Version’: 13,
‘Sec-WebSocket-Key’: ‘MTMtMTU2NDQ5MDMxMDY1OQ==’,
‘Sec-WebSocket-Extensions’: ‘permessage-deflate; client_max_window_bits’ },
path: ‘/’ }

// 源码包路径/lib/http.js
function request(url, options, cb) {
   
   
  return new ClientRequest(url, options, cb);
}

// 源码包路径/lib/_http_client.js
function ClientRequest(input, options, cb) {
   
   
  OutgoingMessage.call(this);
  var agent = options.agent;
  var defaultAgent = options._defaultAgent || Agent.globalAgent;
  agent = defaultAgent;
  this.agent = agent;
  this.agent.addRequest(this, options);
  this._deferToConnect(null, null, () =>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值