调试
- 使用 Chrome Devtools 调试网页,是调试
- 使用 VSCode Debugger 调试 Node 应用,也是调试
他们的共同点在于:
- 有一个调试界面(client) ,比如 Chrome Devtools 、VSCode Debugger。
- 有一个目标调试服务(server) ,比如 网页、Node 应用。
- 调试界面和目标服务之间约定了一个调试协议(protocol) ,比如 Chrome Devtools 的
Chrome Devtools Protocol (CDP),VSCode Debugger 的Debug Adapter Protocol。 - 需要一个传输通道(transport channel) 来传递协议 ,比如使用内部函数调用,或者基于网络传输的websocket方案,usb 传输等等。
| 调试界面(client) | Chrome Devtools 、Safari Inspector 等调试工具,目前 Chrome Devtools 使用率占比最高 |
| 目标调试服务(server) | 手机 web 页面 |
| 调试协议(protocol) | Chrome Devtools Protocol ,Safari 的 Webkit Devtools Protocol |
| 传输通道(transport channel) | 可以是基于 USB 的请求转发、或者基于网络的 websocket 转发,根据不同场景来决定使用的技术 |
Android USB 调试
Android 和 iOS 的 USB 调试过程不太一样,这里先讲 Android 的。
Android USB 调试原理
Android Chrome 在开启调试模式后,会启动 Unix Domain Socket Server(固定端口 9229) ,对其发送 /json/list请求可以获得可调试的页面列表;创建 socket client 并连上该 Server ,找到目标调试页面,对其收发 cdp 数据包,即可控制相应页面或者收到该页面的调试信息。
使用 usb 调试,实际是使用 adb 做了一层端口转发
adb forward tcp:9229 tcp:9229
本地访问 9229 端口实际访问的是 Android 内部的 9229 端口。
PC 启动调试工具时,会创建一个 socket client,接着再通过 adb 连上了 Unix Domain Socket Server ,此后即可就进行 cdp 进行通信。
Android 绕过 USB
解决方案其实很简单,加一层 websocket 进行中转。
在 Android App 内部启动 2 个 socket client :
- 一个连接
Unix Domain Socket Server收发数据, - 另外一个连接 PC 的
socket server用来中转数据
然后 PC 的 socket server 再转发 CDP 数据给 Chrome Devtools
iOS USB 调试
iOS USB 调试原理
iOS 和 Mac 之间进行 USB 通信,采用的是 USB 协议称之为 usbmux ,其本身是私有协议,用于自身应用使用,但是都被破解得差不多了...
usbmuxd 是 usbmux 协议的实现,是一个守护进程,随 iOS 设备和 Mac 设备的系统启动而启动,当 iOS 设备连接上 Mac ,之间的 usb 通信将通过 usbmuxd 这个中间服务进行。
于是如果我们知道了 Web 远程调试对应的 USB 协议,那么就可以取代 Safari Inspector ,实现自己的调试终端。
iOS 绕过 USB
同 Android ,要想取消 USB ,我们也需要启动了一个 websocket 来做指令中转。
要做指令中转,我们首先需要找到远程调试服务的端口。那么问题来了:iOS 的远程调试服务端口是多少?
不像 Android 的调试端口是固定的,iOS 设备的内部服务是启动时动态注册的。
对于这个问题,iOS 提供了一种类似「门卫」的解决方案:内部运行一个守护进程(lockdown),运行在固定端口(62078),支持系统服务访问能力。
于是可以先通过该服务找到 Web 调试服务(com.apple.webinspector)的端口,之后的过程和 Android 一样了。
方案缺陷
首先是使用成本,本地需要另外启动一个 socket server 服务。
那么把 socket server 服务部署在线上呢?的确可以降低用户的使用成本,但是相应的,网络链路变长了,容易出现时延问题,如果是居家办公不在同一个办公网的话就更严重了。
远程调试四要素
| IOS | Android | |
|---|---|---|
| 调试界面(client) | Safari Web Inspector | Chrome Devtools |
| 目标调试服务(server) | IOS Webview | Android Webview |
| 调试协议(protocol) | Webkit Devtools Protocol | Chrome Devtools Protocol |
| 传输通道(transport channel) | USB请求转发 | USB请求转发 |