WebRTC编程——准备WebRTC开发环境

320 阅读10分钟

令人兴奋的新技术通常要求开发人员提升其开发环境的复杂性。WebRTC 也不例外。几乎所有你在 WebRTC 中的操作都是在浏览器中或浏览器之间进行的。虽然你将像其他任何 Web 应用程序一样编写 HTML、CSS 和 JavaScript,但有一些重要的设置可以帮助你顺利完成本书的内容并构建实时 Web 应用程序。

在本章中,如果你还没有安装 Node.js,将会进行安装。你还将了解到如何获取与本书配套的代码副本,并对代码的组织结构进行简要浏览,以便在需要时可以找到所需内容。随后,你将生成并使用自己的自签名证书,用于在开发中提供 HTTPS 服务。即使在开发中,HTTPS 也是完全可靠访问许多新颖、高级 Web API(包括 WebRTC)的必要条件。

你将选择一个支持 WebRTC 的开发浏览器(剧透:Chrome 或 Firefox),启动随本书代码附带的服务器,以服务于正在进行的工作或完整的示例,并英勇地解决浏览器对自签名证书发出的严重安全警告。

这将需要一点工作,但一旦你为自己设置好了这些东西,就不必再多考虑它们了。

这里的所有设置都应该能够在类 Unix 操作系统(包括 macOS)上顺利运行,无需太多麻烦或复杂步骤。

安装 Node.js

为了支持你的本地 WebRTC 开发,我编写了一个小型服务器,它依赖于 Node.js——一个非常流行的 JavaScript 运行时,你可能已经熟悉并且安装过了。让我们确认一下你是否已经安装了 Node.js,如果没有,安装一个。

如果你不确定是否安装了 Node.js,可以在命令行中运行 which node。如果你已经安装了 Node.js,会看到显示其安装路径的输出(如果你已经有一段时间没有更新它,现在可能是个好时机)。
如果你没有看到任何输出,或者你确定自己还没有运行 Node.js,也不用担心:有几种不同的方式可以安装它。你可以从 Node.js 官网 找到、下载并运行适用于你的操作系统的 Node.js 安装程序。或者,如果你的操作系统有可用的包管理器,如 MacOS 的 Homebrew 或 Linux 的原生包管理器,你也可以通过这种方式安装 Node.js。

无论你选择哪种方式安装 Node.js,通常建议运行最新的 LTS 版本。

为了确认是否安装成功,安装 Node.js 后,你可以在命令行中运行 which nodewhich npm,这些命令会报告 Node.js 及其包管理器 npm 的安装位置。这仅仅是确认你已成功安装了 Node.js,并且命令行知道在哪里可以找到它。

下载支持代码并安装依赖项

设置好 Node.js 后,你应该从 pragprog.com 下载本书的代码。下载并解压 ZIP 文件后,将解压后的 code/ 目录移动到你可以方便地从命令行访问的位置。你可能还希望将该目录重命名为比 code/ 更易识别的名称。

完成这些步骤后,使用命令行导航到你设置的目录。在那里,你需要安装在本书中使用的服务器依赖项。运行以下命令:

$ npm install

大量输出会填满终端屏幕,但安装通常只需几分钟,可能更短。

如果看到有关弃用包的警告,你可以尝试运行 npm audit fix 或更激进的 npm audit fix --force 来解决问题。不过,对于 WebRTC 开发,你可以完全忽略这些警告。

熟悉代码目录

我为本书的配套代码准备了示例文件夹,里面包含我编写的示例,以及一个单独的启动目录,供你在阅读本书时跟随操作和自己实验使用。

以下是你在代码目录中会找到的内容和位置的简要介绍:

  • 本书的完整示例位于 demos/ 目录下的各自子目录中。你会在本书中多次看到对这些文件的引用。
  • www/ 目录是供你在阅读本书时使用的工作目录。如果你遇到困难,可以随时将你的工作与 demos/ 目录中的文件进行比较。别忘了低声咒骂我,这会让你感到舒心。

在阅读本书的过程中,你会经常使用这两个目录。但配套代码还包括一些其他文件和目录,你可能会对它们感兴趣:

  • deploy/ 目录包含一个独立的 WebRTC 应用程序,你将在第8章《将 WebRTC 应用部署到生产环境》中使用它。
  • server.js 文件包含一个使用 ExpressJS 框架的基本 Web 服务器。该文件包括本书后面讨论的基本信令通道。
  • scripts/ 目录包含一个服务器启动脚本 start-server,它(不出所料)用于启动服务器,但你也可以简单地在命令行中运行 npm start 来启动服务器。

为了进一步学习和未来的实验,你会在 _starter/ 目录中找到用于建立对等连接的启动脚本。p2p.js 包含在两个对等端之间建立连接所需的逻辑,而 multi.js 则增强了建立三个或更多对等端之间连接的逻辑。

在开发中提供 HTTPS 服务

为了开发 WebRTC 应用程序,有必要将你的开发环境配置为提供 HTTPS 服务。浏览器禁止访问许多 API,包括那些访问麦克风和摄像头的 API,除非你使用 HTTPS,即使是在开发环境中也是如此。

要在开发中提供 HTTPS 服务,你需要创建并使用自己的自签名证书。生成自签名证书并不需要太多工作,但你仍然可以让朋友们对你能在 localhost 上提供 HTTPS 感到印象深刻。

尽管自签名证书不适合在开放网络上使用,但它们完全可以接受用于在本地网络中进行测试。你测试的浏览器可能会强烈抗议,并尽力吓唬你不要使用自签名证书。如果这些措施不起作用,它们可能会让你感觉不好。但不要担心,也不要感到沮丧:在本章末尾,我们会化解这些不必要的恐吓和羞耻战术。

生成自签名证书

你需要使用 openssl 在操作系统上生成自己的证书和密钥文件。MacOS 和几乎所有类 Unix 操作系统和 Linux 发行版都自带了 openssl。如果你是 Windows 用户,可能需要自己安装 openssl。OpenSSL 的 Wiki 维护了一个可下载的二进制文件列表。如果你在 Windows 上运行 Git Bash,它已经包含了 openssl.exe,你也可以使用它。

在生成证书文件之前,你需要为它们创建一个容易记住的存放位置。我建议在你的主目录中创建一个 Certs 目录:

$ mkdir ~/Certs

你下载的本书配套代码中包括了一个脚本,你可以运行它来生成你的证书文件。为此,你需要切换到存储本书代码的目录。基本命令是 npm run ssl-keys,它需要两个参数:你创建的目录的路径(keydir)和自签名证书过期前的天数(numdays)。

例如,要在 ~/Certs 目录中创建约五年(1825 天)后过期的自签名证书文件,你可以在本书代码目录中运行以下命令:

$ npm run ssl-keys --keydir="$HOME/Certs" --numdays=1825

无论你选择什么值,请使用 $HOME 变量而不是波浪号 ~,并确保在等号周围没有空格。

如果你是一个谨慎的人,可以在运行脚本之前查看 package.json 文件中的 ssl-keys 脚本。它基于 Let’s Encrypt 推荐的一个命令,Let’s Encrypt 通常提供可以在面向全球的网站上使用的免费证书。如果你愿意,可以前往 Let’s Encrypt 的原始文章,将命令复制到你的命令行中,而不是使用 npm 脚本。在运行 Let’s Encrypt 命令以生成证书和密钥文件之前,你需要切换到你的证书目录。默认情况下,openssl 会生成一年后过期的证书。如果你想生成有效期更长的证书,可以在 Let’s Encrypt 脚本中添加 -days 选项,后跟一些天数,例如 -days 1825 来创建五年期的证书。

无论你选择何种方式生成密钥,一旦按下回车键,只需片刻就可以在你选择的目录(如 ~/Certs)中生成密钥和证书文件。创建这些文件是提供 HTTPS 服务的第一步。但你还需要确保你运行的任何脚本和服务器都能够轻松找到你的证书文件。接下来我们来设置这些内容。

将证书文件的位置存储在环境变量中

你需要从命令行的启动脚本中导出两个环境变量。这些变量将指向你自签名证书文件的位置。你的启动脚本位于主目录中的一个文件中,文件名为 .bashrc.bash_profile(如果你使用的是 bash),或者是 .zshrc(如果你使用的是 zsh),或者甚至可能是 .profile 文件。

无论你的命令行使用哪个启动文件,用你喜欢的文本编辑器打开它,并添加以下行:

# SSL Keys
export LOCALHOST_SSL_CERT="$HOME/Certs/localhost.crt"
export LOCALHOST_SSL_KEY="$HOME/Certs/localhost.key"

确保在等号 = 周围没有空格。如果你将密钥保存在 ~/Certs 之外的其他位置或将它们命名为不同的名称,也不要忘记调整路径。保存启动文件后,使用 source 命令在终端中重新加载它。你需要参考命令行使用的文件名称。在这个例子中,文件名为 .zshrc

$ source ~/.zshrc

作为快速检查,你可以使用 echo 命令输出这些变量的值,确认命令行已经识别了这些变量。为此,在变量名称前加上美元符号 $

$ echo $LOCALHOST_SSL_CERT

如果一切按计划进行,你将看到命令行 shell 输出的证书位置。以 MacOS 为例,它可能类似于 /Users/username/Certs/localhost.crt。如果需要,你也可以用相同的方法检查 LOCALHOST_SSL_KEY 的值。

选择开发浏览器

使用最新版本的 Chrome 或 Firefox 将为你提供最佳的开发体验。我个人更喜欢 Firefox 开发者版本,但选择权在你手中。

Safari 怎么样?

Safari 在 WebRTC 实现方面一直落后,但自 2022 年 4 月发布的 Safari 15.4 以来,它也达到了应有的标准。如果你选择 Safari 作为开发浏览器,或者你想在 iPhone 或 iPad 上测试你的工作,请确保运行的是至少 Safari 15.4 版本。

旧版 Safari 和其他浏览器(如版本 80 之前的 Firefox 和版本 75 之前的 Chrome)中不完整的 WebRTC 实现可能会让你头疼不已。请查阅附录 1,了解在旧版浏览器中进行连接协商时可能需要添加的后备代码,只要这些旧版浏览器仍在使用(如果历史可以作为参考,那将是相当长的一段时间)。

无论你选择哪种浏览器,你都需要打开其开发者控制台并禁用缓存,这样在工作时你总是加载最新版本的 CSS 和 JavaScript。Firefox 和 Chrome 都在开发者面板的网络选项卡下提供了“禁用缓存”选项。如果你和我一样,你可能会选择将开发者控制台弹出到一个单独的窗口中,以最大化可用屏幕空间。你将构建响应式界面,充分利用整个视口。你知道界面就像个大明星:如果你在任何方面抢了它们的风头,它们就会让你的生活变得痛苦,并向它们的朋友散布关于你的恶意谣言。

启动和停止服务器

我尽量让你在 localhost 上同时提供自己的工作文件和完成的演示文件变得尽可能轻松。要在你处理自己的文件时提供它们的服务,在命令行中运行 npm run start 或简单地运行 npm start。你的文件更重要,因此它们获得了更方便的命令。

记得安装依赖项

如果你还没有运行过 npm install,请务必在启动服务器之前执行此操作,或者在遇到有关缺少模块的错误时执行。

要提供本书中的完整示例,你需要运行稍微复杂一点的命令 npm run start:demos。请注意,冒号两侧没有空格。

每次启动服务器时,你会在终端窗口中看到类似以下的输出:

signaling-server:   ** Serving from the www/ directory. **
signaling-server:
signaling-server:   App available in your browser at:
signaling-server:
signaling-server:     -> https://127.0.0.1:3000/
signaling-server:     -> https://192.168.1.6:3000/
signaling-server:
signaling-server:   Hold CTRL + C to stop the server.
signaling-server:
signaling-server:   +0ms

每次启动服务器时,它都会告诉你当前正在提供服务的目录(再次提醒:对于你的工作是 www/ 目录,完成的示例是 demos/ 目录)以及至少两个可以从你选择的开发浏览器访问服务器的地址。每当你需要停止服务器时,按住 CTRL + C 即可。

第一次启动服务器时,操作系统可能会通知你某种防火墙限制。由于你最终会从连接到本地网络的其他设备访问此服务器,因此请指示操作系统允许传入连接。

服务器仍在运行时,你可以在浏览器中打开 https://localhost:3000/。当然,localhost 是 127.0.0.1 的快捷方式,如果你喜欢输入数字和点,也可以使用 https://127.0.0.1:3000/。目前不用担心看到的第二个 IP 地址。它几乎肯定与 192.168.1.6 不同,但最终你将能够使用该第二个地址通过连接到本地网络的其他设备测试你的应用程序。

有一个大问题:你绝对必须输入完整的 https:// 协议部分。如果省略了协议,你的浏览器将尝试通过 http:// 建立连接。服务器实际上没有监听 HTTP,而是在监听 HTTPS。不过,浏览器不知道这一点,因此它会轻蔑地告诉你它无法连接。而你将花费大量时间寻找那个丢失的 s,尤其是在那些隐藏 http:// 协议字符串的浏览器中,这会更加难以发现。

一旦输入了准确的 HTTPS 地址,你会立即遇到一个障碍。你的浏览器要求你在地址栏中输入 https://,现在却想让你知道它对你的自签名证书有很大的问题。你将不会看到服务器正在提供的页面,而是会收到一个安全警告。

绕过浏览器安全警告

在你将浏览器指向服务器的任何本地 https:// URL 之后,浏览器的视窗将充满严重的警告、不祥的预兆和古老诅咒的传说。例如,Firefox 开发者版会显示如下画面。

image.png

在开放的网络上,这些安全警告是好事。但在开发过程中,它们只是夸张、过度担忧的麻烦。

好消息是,你可能只会在第一次访问本地地址时看到这个警告,你也只需执行这些步骤一次。要让 Firefox 放松并让你继续工作,点击“高级...”按钮,然后在出现的框中点击“接受风险并继续”按钮。在 Chrome 上,同样需要点击“高级”并点击“继续访问localhost(不安全)”链接。

Safari 让你通过一系列不同的步骤来接受自签名证书:当 Safari 显示警告页面时,点击“显示详细信息”,然后点击“访问此网站”的超链接。在 iOS 上,你只需要做这些事情即可,幸运的是,这就足够了。但在 MacOS 上,接下来会出现一个弹出窗口,询问“你确定要在非私人连接上访问这个网站吗?”点击“访问网站”,然后你会看到另一个弹出窗口:“你正在更改证书信任设置。”点击“使用密码...”,然后输入你用于登录 Mac 的密码。

一旦你完成这些步骤,你就会看到我为你编写的概述页面。在演示部分,该页面包含指向各个演示的链接。在工作目录(www/)中,你会看到一些说明和鼓励内容。

image.png

下一步

太好了。通过在你选择的开发浏览器中以 HTTPS 查看其中一个或两个页面,你可以确信自己已经成功准备好了 WebRTC 开发环境。你已经安装了 Node.js,并且已经找到、下载并使用命令行找到了本书的配套源代码并安装了其依赖项。你还生成了自己的自签名证书文件,以便在开发过程中提供 HTTPS 服务。最后,在经过一些安全问题的磋商后,你已经说服浏览器接受你的自签名证书。

在下一章中,我们将直接开始使用你在本章中安装并启动的服务器。你将使用它的信令通道组件(我们还没见过),同时构建你的第一个 WebRTC 应用的用户界面。正如我们将看到的,WebRTC 与用户界面紧密结合。因此,我们需要确保为界面编写的代码与我们将编写的 WebRTC 浏览器 API 代码一样精心设计和工程化。让我们开始吧!