作为一家流媒体公司,我们力求让每个用户都能在任意平台上通过 Tubi 观看流媒体资源。无论是智能手机还是智能电视,抑或是游戏主机,甚至诸如 EchoShow 或者 Nest Hub 这种多模式设备,你都能在其中找到 Tubi 的身影。支持如此多的设备当然能带来很棒的用户体验,但我们的开发者也面临诸多挑战。其中之一就是能否通过一个统一的调试工具加快我们的开发效率。
在本篇文章中,我们会分享我们所遇到的难题及对应的解决方案。
我们如何调试如此众多的设备?
在我们常规的 PC 或者移动端开发的时候,开发者一般都会有各种调试工具来帮助他们修复问题。桌面浏览器基本都配备有强大的调试工具。而在移动端的平台我们一般可以通过 Safari/Chrome 浏览器接入来进行远程调试。但有的时候部分应用不会给予我们调试权限,或者设备本身没有提供调试接口,例如 EchoShow[1]。这个时候我们可以通过 WEB 远程调试工具来解决问题,知名的有 Eruda[2]和 vConsole[3]。(如下图)
在基于 Android TV 的设备中,例如亚马逊的 Fire TV,我们可以使用 ADB (Android Debug Bridge[4]) 来连接设备和开发者的设备,从而让开发者可以使用 Chrome 的开发者工具进行调试。而其他平台都有各自的调试工具。
-
Xbox One,作为著名的家用游戏主机,你只能使用 Visual Studio 和 Fiddler[5]进行调试。
-
三星则在他们的 Tizen Studio 中内置了远程调试工具,换言之,你必须要先安装 Tizen Studio 才能开始调试。
-
Chromecast,谷歌开发的投影设备,允许开发者使用 Chrome 的开发者工具进行调试。然而你要事先在 App 的控制台中将你的设备加入白名单。
尽管大部分平台都具备调试工具,但他们都差别巨大。这就要求开发者们都安装了相应的软件并且对它们非常熟悉。
更好的调试方法
让开发者掌握这么多种工具是不现实的,他们需要更适用的开发者工具。对 Tubi 而言,我们认为理想的开发者工具应该支持以下几个需求:
-
它应该支持我们所有的 HTML5 平台。
-
Web 开发者能够使用它访问修改所有 Web 开发者能接触到的资源,例如 DOM,网络请求和 cookies 之类。
-
我们应该可以通过它在 App 上更便捷地执行 JavaScript 指令。
-
它可以支持跨网络调试,无需使用者和设备处于同一个局域网下。
-
它应该支持插件扩展。
感谢伟大的开源社区,我们找到了几个致力于此的项目。DevTools Frontend[6]是 Chrome DevTools 的 UI 项目。Chrome DevTools 是最流行的开发者调试工具,使用他们的 UI 界面可以让我们的工程师轻松上手。与此同时,DevTools Backend[7]可以满足我们的后端需求。
这个项目是由 Christian Bromann[8]创建的,它能够允许我们调试任意目标,完美地满足了我们的所有需求。
那我们怎样将相关的信息从目标机器发送到调试者的客户端呢?我们通过 Chrome DevTools Protocol[9]将 Chrome DevTools Protocol 和 DevTools Frontend 以及 DevTools Backend 结合起来,我们开发了 remote debugger 来帮助我们在任意情况下调试任意机器。接下来,让我们看看它们是怎样工作的。
Remote debugger
Remote debugger 的架构其实非常简单:
-
我们将需要调试的 OTT 设备称作目标设备 (debug target),我们会通过一个嵌入的 JS 脚本来收集信息。
-
调试客户端 (debug client) 就是我们的开发者工具界面,我们通常会使用自己的电脑接入。
-
服务端 (debug server) 会列出所有可调试的页面并且负责在目标设备和客户端间传送消息。
-
我们使用 WebSocket 分别链接目标设备和服务端,调试客户端和服务端,这允许我们可以在跨网络情况下进行设备调试。
基于上述架构,我们可以轻松执行我们的 JavaScript 指令。我们只需要在调试客户端输入指令,然后指令就会被发送到服务端,服务端再将指令中转到目标设备,最后目标设备中嵌入的脚本会运行我们的指令。
我们所有发送的信息都会遵循 Chrome DevTools Protocol (CDP),所以你可以想象到我们其实是三层架构。
接下来让我们通过三个不同的例子来了解 remote debugger 是如何具体工作的。
从节点获取 CSS 样式
在下面的 GIF 中,你可以看到我们如何使用 remote debugger 来获取某个节点的 CSS 样式。
当我们点击元素面板的节点的时候,调试客户端会发送一额事件来调用 `CSS.getMatchedStylesForNode` 方法。
然后我们会在目标设备收集相关的信息并且如下图一样返回。
最后 DevTools Frontend 会将这个信息渲染在屏幕上容我们查看,就像平常我们在 Chrome 浏览器上看到的一样。
执行 JavaScript 指令
如果我们想在目标设备上执行 JavaScript 指令,我们会使用相同的方式进行操作。假设我们想知道目标设备的 UA,我们可以在控制台输入 `navigator.userAgent` 然后敲击回车。
调试客户端会马上发送一个 “Runtime.evaluate” 事件。
目标设备会执行该表达式并且返回结果。
然后我们就可以在客户端的控制台上看到结果。
分析和确认数据上报
Remote debugger 能够有效确保我们数据流的数据质量。作为一个数据驱动的公司,数据质量对 Tubi 至关重要。
为了确保 OTT 设备上发出的数据上报事件的正确性,我们以前会使用诸如 Charles/Fiddler 之类的代理工具又或者平台提供的调试工具。但这种方式并不总是有效的,例如在 XboxOne 和三星设备上。除此以外,如果我们需要在 Android/Fire TV 上进行 SSL 代理,我们需要安装并信任自签 SSL 证书。
不过现在,既然我们已经有了 remote debugger,我们就不再需要执行这些繁琐的步骤了,只需要打开调试界面然后就像你平常在浏览器中查看网络面板就可以了。
Remote debugger 本身也给我们带来了其他便利。例如我们现在可以直接修改程序中的值并马上得到反馈。如下图我们修改了实验分配的参数。
未来之路
尽管 Remote debugger 没有原生调试设备强大,但它经济有效,能够帮助我们快速解决问题。Remote debugger 本身也不仅仅是一个调试工具。它使我们能够在不同平台上控制自己的应用。更美妙的是 Chrome DevTools frontend 具有完善的插件机制,我们可以利用它们来构建自己的 Tubi 调试面板。
我们可以通过 remote debugger 来修改网络请求,也可以通过 Redux 插件来调试我们的 React store。
在日后的文章里,我会给大家深度剖析我们的 Tubi 调试面板。
任何工具都不是银弹,但是好的工具可以让我们的开发事半功倍。随着 Tubi 团队日益壮大,我们总会寻找更好的方式来提升我们的开发体验和开发效率。如果你也对这样的工作方式感兴趣并且希望致力提高开发者的产出能力,请加入我们!
作者:Heng Zhong, Tubi Senior Front-end Engineer
点击 “阅读原文” 查看英文版