« 上一篇下一篇 »

浅析微信x5内核inspect调试

最近做一个基于微信公众号的产品,用到了微信的x5浏览器调试的功能,这里简单的做个总结。站在微信客户端角度来讲,微信公众号其实就是由一系列的网页组成的程序,它运行在微信内置的浏览器中,产品的调试就是网页的调试,这里就涉及到一个远程调试网页的问题。我们需要在开发机上远程调试位于手机上的微信内置浏览器中的网页。庆幸的是现在这已经不是什么大问题,腾讯X5浏览服务中已经提供了相应的解决方案,相关资料在 
在分析腾讯X5的方案前,我们先回顾一下google的解决方案:
利用google chrome浏览器支持远程调试也已经有蛮长一段时间了,它本身也在不断的升级和变化,我们先来看看它以前的模式,然后再看看现在的模式。
以前的模式的资料在:
这里需要重点说明的部分是我们在进行远程调试时 在开发机的chrome浏览器中运行的调试工具其实本身就是个web程序,名字叫做 WebInspector 它是由html,css,javascript写成的,chrome浏览器自带了这个web程序,路径在chrome-devtools://devtools/bundled/devtools.html,新版的chrome浏览器路径已经改成了chrome-devtools://devtools/bundled/inspector.html,可以自行打开看看,你如果不信这是网页程序的话,你可以打开后再按f12呼出chrome原生的网页调试工具,你会神奇的发现屏幕上2个一模一样的调试工具,其中一个调试工具正在调试另外一个调试工具。如图:
这个调试工具本身就是个web程序,那么我们也可以把它当一个网站放到互联网上去访问,google确实这样做了,比如你可以访问:
这个调试工具,严格说应该叫做调试前端工具,它由html,css,javascript实现,怎么跟后端的被调试程序通讯呢,这里使用的是websocket的方法。通过文档我们知道调试前要执行命令
adb forward tcp:9222 localabstract:chrome_devtools_remote  通过adb将9222端口转发到手机端去。流程如下:

WebInspector(html,css,javascript实现,运行在浏览器中) ==>websocket==>adb守护进程==>手机端adbd==>被调试程序
chrome后来又推出了新的支持远程调试的方法,新的方法号称不再需要adb了,操作也更加简单,与chrome浏览器集成度更高了。资料参考:
虽然号称不需要adb,其实也只是chrome内部集成了adb的功能而已,所以外部就不需要adb这个程序配合了。当然如果外部存在adb守护进程的话,chrome还是会尝试连接外部adb的5037端口建立连接。 同时既然不需要adb了那也不存在9222端口进行转发到手机了,那做为调试前端的WebInspector又怎么跟后端被调试程序进行通讯了,答案是chrome暴露出来的js内部接口,
WebInspector通过javascript调用chrome内部的调试功能,直接与chrome浏览器通讯。
WebInspector==>内部接口==>chrome浏览器==>手机端adbd==>被调试程序

或者是

WebInspector==>内部接口==>chrome浏览器==>5037端口==>adb守护进程==>手机端adbd==>被调试程序

最后看看远程调试微信webview是如何实现的,其实用的就是chrome远程调试老的方法。

第一步在手机上安装TbsSuiteNew.apk,这个app关键的功能就是将微信的浏览器内核换成一个暴露了9222调试端口的x5浏览器内核。
第二步是运行调试包里面的inspector.py,打开这个inspector.py文件看看代码,就知道其实主要就做了两件事情,第一就是利用adb forward命令将本机9222端口转发到手机端的9222端口上,然后就是启动一个简单的web服务器,它会监听9223端口,这个web服务器的目的就是让浏览器能够通过http://localhost:9223/inspector.html这样的地址可以访问到我们前面说到的WebInspector这个由html,css,javascript实现的调试前端工具。如图:
有兴趣的人可以自己去研读这些代码。
第三步在开发机中用chrome浏览器打开http://localhost:9222,因为9222端口已经转发到了手机上的x5内核,所以这个时候手机上的x5内核就会返回待调试的页面给开发机上的chrome浏览器,然后用户选中某个要调试的页面,又会打开http://localhost:9223/inspector.html?host=localhost:9222&page=2这样的页面,前面已经说过,这个时候就已经运行起了WebInspector这个调试前端工具,然后WebInspector会通过websocket的方式连接本地的9222端口,因为这个端口已经转发到了远端手机上的x5内核的9222的端口上,到此调试会话已经建立起来,用户就可以进行调试工作了。事实上如果手机和开发机都连接在同一个内网中,那么不用adb也没问题,假设我们的手机ip地址为192.168.104,那么这个时候我们只需要先将http://localhost:9222 替换成http://192.168.1.104:9222。 然后把具体调试页也换成如 http://localhost:9223/inspector.html?host=192.168.1.104:9222&page=2 这样子就可以了。
下面是调试"这个调试工具"的截图,可以清楚的看到通过websocket连到了9222端口:
流程如下:
WebInspector(开发机)==>websocket(本机9222端口)==>adb守护进程(开发机)==>adbd(手机端)==>腾讯X5内核(手机端)
或者是
WebInspector(开发机)==>websocket(192.168.1.104:9222端口)==>腾讯X5内核(手机端)

总结:

WebKit 是一个开源的浏览器引擎,apple和google等都在使用它,虽然现在google推出了blink,但是它也是一个webkit的派生品,微信的x5内核也是一个webkit的派生品,所以如果有兴趣进一步了解,完全可以把webkit源代码下载下来研究一下,Inspector的大部分代码都在WebCore/inspector下,有兴趣可以研读。
一些有用的站点和资料:
http://alpha.publicore.net/_/brackets/src/LiveDevelopment/Inspector/inspector.html
https://developer.chrome.com/devtools/docs/debugger-protocol
http://x5.tencent.com/index