You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1947年9月9日,哈佛大学在测试马克II型艾肯中继器计算机的时候,一只飞蛾粘在一个继电器上,导致计算机无法正常工作,操作员把飞蛾移除之后,计算机又恢复了正常运转。于是他们将这只飞蛾贴在了他们当时记录的日志上,并在日志最后写了这样一句话:First actual case of bug being found。这是他们发现的第一个真正意义上的 bug,这也是人类计算机软件历史上发现的第一个 bug。他们也提出了一个词,“debug(调试)”了机器,由此引出了计算机调试技术的发展。
通讯模式和消息结构:
对于每个页面的所有操作,远程调试协议将其划分成了不同的命令域,如Browser、Dom、Debugger和Network等等,每个域定义了不同的命令和事件。在开发调试过程中,浏览器内核和远程客户端通过WebSocket发送消息进行通信,消息基本上分两种格式,一种是含有 message id 的,另一种是不含 message id 的,分别代表俩种通讯模式:
一、调试技术的起源
对于每位开发者而言,bug已经是不能再寻常的东西,debug也是家常便饭的事情。然而寻根溯源起来,还得从上个世纪五十年代讲起。
1947年9月9日,哈佛大学在测试马克II型艾肯中继器计算机的时候,一只飞蛾粘在一个继电器上,导致计算机无法正常工作,操作员把飞蛾移除之后,计算机又恢复了正常运转。于是他们将这只飞蛾贴在了他们当时记录的日志上,并在日志最后写了这样一句话:First actual case of bug being found。这是他们发现的第一个真正意义上的 bug,这也是人类计算机软件历史上发现的第一个 bug。他们也提出了一个词,“debug(调试)”了机器,由此引出了计算机调试技术的发展。
二、Chrome 开发者工具
对于web前端而言,我们每天都在使用开发调试工具进行查看dom结构、js断点和查看分析登录请求等操作,最熟悉的开发调试工具 应该莫过于Chrome的Devtools和Firefox的FireBug了。
Chrome 开发者工具其实是一个用 HTML,JavaScript 和 CSS 写的 Web 应用程序,被集成在浏览器中。其基于远程调试协议,与浏览器架构关系如下:
由图可知:
事实上,Chrome开发者工具不仅只是可以在当前的浏览器页面直接打开,它作为一个客户端(开源),也可以用来调试任何支持远程调试协议的浏览器。
三、远程调试协议(remote debugging protocol)
远程调试协议Webkit 在 2012 年就已经引入,目前所有 Webkit 内核的浏览器都支持这一特性。远程调试协议基于 WebSocket,利用 WebSocket 建立连接 客户端(如DevTools) 和浏览器内核的快速数据通道,Chrome的Devtools仅仅只是Webkit远程调试协议的一个应用案例。
对于每个页面的所有操作,远程调试协议将其划分成了不同的命令域,如Browser、Dom、Debugger和Network等等,每个域定义了不同的命令和事件。在开发调试过程中,浏览器内核和远程客户端通过WebSocket发送消息进行通信,消息基本上分两种格式,一种是含有 message id 的,另一种是不含 message id 的,分别代表俩种通讯模式:
为了更加方便Chrome extension的开发,Chrome调试器扩展API提供了更高级别的API ——Chrome Debugger API。此API隐藏请求ID并处理请求与其响应的绑定,因此允许sendCommand在回调函数调用中处理结果。每个 command 包含 request 和 response 两部分,request 部分指定所要进行的操作以及操作说要的参数,response 部分表明操作状态,成功或失败。
以Debugger Domain为例,
我们可以通过devtools来查看Devtools Extension与浏览器内核实际通信的数据情况,步骤如下:
1、开启开发者工具实验模式:
2、打开协议监控tab
之后我们便可以看到:
四、Chrome的远程调试模式:
从上面我们已经知道,Devtools是如何基于远程调试协议与浏览器内核进行交互的了,然而,不仅仅如此,Chrome还可以开启远程调试模式,允许外部客户端(支持远程调试协议)对其进行调试。
首先,以远程调试模式打开Chrome:
./chrome --remote-debugging-port=9222
之后调试数据会转发到本地9222端口,浏览器输入localhost:9222/json可以看到:
其中我们可以看到每个tab页面对应的websocket url,通过该url建立连接便可以和系统内核进行通信了。
我们可以采用Chrome内置的工具与其建立连接进行调试,步骤如下:
1)打开Chrome 内置客户端,在浏览器输入:
http://localhost:9222
可以看到以下界面:
2)或者在chrome://inspect界面,我们可以发现,此时本地浏览器也可以被作为一个remote device来调试了。
3)我们也可以采用一个外部的调试工具,如node程序,vscode插件等,通过从9222端口获取到各个页面的json数据,然后进行websocket连接进行通信,进行实现各种丰富的开发调试功能。
五、移动端远程调试技术:
从上面看,chrome等浏览器的远程调试模式似乎有点鸡肋,我都有Devtools工具了,何必还要多此一举去开启远程调试模式用其他工具来调试。别急,远程调试模式真正发挥作用的还是移动端设备的调试场景。移动端设备有运行环境,却没有合适的开发和调试环境,借助于webkit的远程调试模式,可以使得我们很方便的查看和调试移动端设备。
移动端web远程调试技术很多种,像weinre等在代码中嵌入脚本的就不说了,我们以基于webkit远程调试协议的方式来讲解。
从上面我们已经知道,移动端chrome开启远程调试模式后json数据会被打到debugging端口(localhost:9222),因为安全考虑,chrome限制了只能是本地localhost的,不能打到指定ip之上。此时,需要通过某种方式,将移动端9222端口的数据绑定到pc端,之后才能PC端便可以通过PC端本地端口与移动端页面进行调试。
1、端口绑定方式:
adb forward tcp:9222 localabstract:chrome_devtools_remote
#在本地主机A1登陆远程云主机B1,并进行本地端口转发。2000端口绑定本地所有网卡 ssh -L 2000:localhost:3000 [email protected].*.*
六、调试服务器脚本(node程序):
2016年,Node将 Chrome浏览器的"开发者工具"作为官方的调试工具,使得 Node 脚本也可以使用图形界面调试,这大大方便了开发者。开启调试方式如下:
node --inspect --debug-brk index.js
然后通过chrome://inspect可以看到app.js的调试入口,打开之后出现Devtools的定制版,只有四个Tab,移除了和服务器脚本调试无关的部分。
可以发现,node脚本调试的原理与chrome js脚本相似,其内置V8支持远程调试协议,开启调试后作为一个server端,devtools客户端通过websocket与其建立连接进行通信。
六、总结
至此,我们已经介绍了本地调试和远程调试已经隐藏在其背后的通讯原理。远程调试协议作为一个强大的通用的协议,支持了不同server或客户端的通信。
浏览器的调试,其实最后都落脚到引擎:渲染引擎和 JavaScipt 引擎。对于css的修改、js的断点等,如何落实到渲染引擎上,上下文环境切换,函数调用栈追踪等等,还有更多东西值得挖掘。
The text was updated successfully, but these errors were encountered: