什么是 PeerJS?
PeerJS 是浏览器 WebRTC 实现的 JavaScript 封装程序,用于简化 Web 应用程序中 WebRTC 的实现。WebRTC 是一个开源项目,为网络浏览器和移动应用程序提供了一个通信框架。PeerJS 库提供了一个易于使用的界面,可简化 WebRTC API 的采用。
PeerJS API 为连接事件和接口提供监听器,以简化数据交换。这种连接还支持实时通信,这意味着您可以为视频聊天应用程序集成音频或视频流。
你可能想知道这一切的注意事项是什么,没错,有一个。你需要一台服务器来充当信令服务器(可能还有 STUN 或 TURN 服务器),以便在对等网络之间建立中介连接。虽然 PeerJS 提供了免费使用的 PeerJS 服务器版本,但这种设置并不适合网络实时通信的生产环境。
通过 Cloud Run 配置 PeerJS 服务器
对于希望实施 WebRTC API 的开发人员来说,运行专用服务器的主要障碍是成本高昂。考虑到对公共 IP 和负载平衡的需求,其成本也在不断增加。为了解决这个问题,您可以使用 Cloud Run。
Cloud Run 是一个用于容器化应用的全面管理平台。它允许您定义使用容器作为底层映像的工作负载和服务,这些工作负载和服务由 Cloud Run 平台管理并自动扩展(向上和向下)。
开发人员可使用 Cloud Run 运行 PeerJS 服务器的开源镜像,并拥有一个可完全控制环境的服务器实例。这是 PeerJS 客户端从浏览器连接的服务器。
Cloud Run 的主要优势在于其慷慨的免费套餐,允许业余开发者和小规模应用程序在该平台上运行应用程序。这些应用程序可以处理媒体连接和媒体流(音频或视频流)。
Cloud Run 的工作原理与 Lambda Functions 相似,容器在需要时开启,确保只需为使用付费。这意味着它也有同样的缺点,那就是冷启动。这是指服务器关闭后又重新开启,这可能会给初始请求增加几秒钟的时间。
配置实现
下文将介绍如何配置所有组件,以确保它们都能正常工作。所有基础架构元素都将通过 Terraform 进行设置,以确保一致性。
在开始实施之前,您应该确保您希望用户使用的网络浏览器支持点对点通信。
请注意以下免责声明。该解决方案实际上是免费的,因为免费套餐涵盖了一定的使用级别。例如,如果远程对等方开始打开多个连接,并持续使用该应用一个月,你可能会产生一些费用。设置计费预算和警报是您应该遵循的良好做法,您需要对自己的云使用情况负责。
配置 GCP 帐户
首先在Google Cloud中创建一个帐户。您可能需要添加信用卡详细信息,但不应开始产生费用。如果您是新用户,您可以获得价值 300 美元的积分。
创建帐户后,安装 gcloud CLI。它将确保 Terraform 在执行所有请求时具有必要的凭据。安装完成后,运行登录命令对工具进行授权。
配置 Google Cloud 提供商
在定义服务器的 Terraform 资源和计费预算之前,您应该在 Terraform 中为 Google Cloud 模块创建提供商配置。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "5.3.0"
}
}
}
# Configure the GCP provider
provider "google" {
project = var.gcp_project_id
region = var.gcp_region
billing_project = var.gcp_project_id
user_project_override = true
}te
你可能会注意到,有些配置使用了变量或本地值,定义:
locals {
display_name = "tictactoe"
# GCP APIS
apis = ["billingbudgets.googleapis.com", "run.googleapis.com", "iam.googleapis.com", "cloudresourcemanager.googleapis.com", "cloudbilling.googleapis.com"]
# Server locals
server_name = "${local.display_name}-server"
server_image = "docker.io/peerjs/peerjs-server:latest"
server_key = md5(var.base_server_key)
}
variable "base_server_key" {
type = string
description = "Server key to be used in connections."
}
variable "gcp_region" {
type = string
description = "Region to use for GCP. By default is `europe-west1`."
default = "europe-west1"
}
variable "gcp_project_id" {
type = string
description = "ID for the GCP project compute resources."
}
启用相关的 Google Cloud API
Google Cloud 的服务模型与 API 配合使用。在使用服务之前,需要启用其API。可以使用 Terraform 以编程方式执行此操作,这样做的好处是可以声明您在项目中配置的内容。
resource "google_project_service" "apis" {
project = var.gcp_project_id
for_each = toset(local.apis)
service = each.key
disable_on_destroy = false
}
创建 Cloud Run 服务
对于 PeerJS 服务器,我们使用 PeerJS 提供的开源实现。PeerJS 背后的团队非常友好地提供了一个已构建好的 Docker 镜像,网址如下:docker.io/peerjs/peerjs-server。你也可以自己生成镜像,但这样可以节省托管镜像的成本。
下面的 Terraform 代码段包含了在 Cloud Run 中部署 PeerJS 服务器的过程:
resource "google_cloud_run_service" "default" {
name = local.server_name
project = var.gcp_project_id
location = var.gcp_region
# Metadata to note allow all ingress.
metadata {
annotations = {
"run.googleapis.com/ingress" = "all"
"run.googleapis.com/ingress-status" = "all"
}
}
# Container template
template {
metadata {
# Ensure the correct annotations for scale and not continuously allocated.
annotations = {
"run.googleapis.com/startup-cpu-boost" = false
"autoscaling.knative.dev/maxScale" = 1
}
}
spec {
# Container request limits.
container_concurrency = 50
timeout_seconds = 300
containers {
# Image and port configuration for the Peer JS server.
image = local.server_image
ports {
container_port = 9000
}
# Arguments you send to the container.
args = ["--allow_discovery", "--key", "${local.server_key}"]
# Resources allocated for the container.
resources {
limits = {
cpu = "1000m"
memory = "512Mi"
}
}
# Probe to determine if the container started correctly.
startup_probe {
timeout_seconds = 240
period_seconds = 240
failure_threshold = 1
tcp_socket {
port = 9000
}
}
}
}
}
# Traffic allocation to the revisions is always 100%.
traffic {
percent = 100
latest_revision = true
}
}
请注意以下配置:
- 入口注释允许来自任何地方的流量。
- 模板元数据注释将容器实例的最大数量限制为 1,并防止 CPU 持续开启(这会增加成本)。文档没有明确说明这一点,但容器实例的最大数量是 1(在App Engine 部署示例中概述了这一点)。
- 容器并发限制了同时处理的请求数量。如果预期流量较高,可以更改。
- 根据 PeerJS 服务器文档,容器端口必须是 9000 端口。
- 你可以向容器发送参数,从而定制部署。我建议添加
allow_discovery
标记和服务器密钥选项,以使你的实施更加稳健。 - 容器的容量限制为 1 个 vCPU 和 512 MB 内存,这对于初始实施来说绰绰有余。全面生产部署可能需要分配更多资源。
- 配置启动探针时,确保端口是容器端口,如端口 9000。
- 所有流量都会自动转到最新版本。有必要防止远程对等方使用旧版本。
要使实例对互联网开放,还需要一个允许所有用户(包括未验证用户)向服务器发送请求的策略。除此之外,还有 Cloud Run 的策略附件。以下 Terraform 资源可以解决这个问题。
# Policy for no authentication.
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = [
"allUsers",
]
}
}
# Policy to allow unauthenticated requests.
resource "google_cloud_run_service_iam_policy" "noauth" {
location = google_cloud_run_service.default.location
project = google_cloud_run_service.default.project
service = google_cloud_run_service.default.name
policy_data = data.google_iam_policy.noauth.policy_data
}
如果从 Google Cloud Console 部署,请复制 Terraform 文件中的配置,并确保允许所有未经验证的请求。这样,任何远程对等设备都能访问服务器。
创建计费预算
计费预算是部署中最相关的方面之一,因为它能确保您花费(或消耗)的金额是您可以接受的。下面是我配置的计费预算示例。该预算为 1 美元,用完一半后会收到通知。
data "google_billing_account" "account" {
provider = google
display_name = "My Billing Account"
}
# Billing limits for the GCP project.
resource "google_billing_budget" "budget" {
billing_account = data.google_billing_account.account.id
display_name = "Billing Budget"
# Max budget is 1 USD.
amount {
specified_amount {
currency_code = "USD"
units = "1"
}
}
# Alerts at 50% of the budget.
threshold_rules {
threshold_percent = 0.5
}
depends_on = [google_project_service.apis]
}
请注意,要分配预算,首先需要获取与项目关联的计费账户。
配置 Terraform 输出
为 Terraform 创建输出文件,以便更轻松地获取服务器 URI 和服务器密钥的值。
output "server_url" {
value = google_cloud_run_service.default.status[0].url
description = "URL of the Cloud Run server."
}
output "server_key" {
value = local.server_key
description = "Key for the server."
}
如何配置 PeerJS 客户端
首先包含来自 Peer JS CDN 的 PeerJS 库的 JavaScript 文件,还可以自己托管peer min JS 文件。可以在这里获取更多相关信息:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Head content... -->
</head>
<body>
<!-- Add this at the bottom of the body... -->
<script src="https://unpkg.com/peerjs@1.5.1/dist/peerjs.min.js"></script>
<!-- Any other scripts... -->
</body>
</html>
然后,就可以创建一个对等对象,它将处理与其他对等对象的所有连接。请注意,在初始化对等对象时,可以定义对等 ID,该 ID 在所有用户中应该是唯一的。在我的实现中,我在初始化对等对象时定义的对等 ID 如下:
// Generate the ID for the connection, once per load of the tab.
const UUID = window.crypto.randomUUID();
// Server connection information.
// Complete with the URI of your Cloud Run server.
const SERVER_URI = 'example.a.run.app';
// Key will be exposed to front end, that's fine.
// This is the MD5 of the key from Terraform.
const SERVER_KEY = 'XXXX';
const SERVER_CONNECTION = {
host: SERVER_URI,
port: 443,
ping: 1000 * 15, // 15s ping
secure: true,
debug: 2,
key: SERVER_KEY,
};
// Create the peer instance object.
let peer = new Peer(UUID, SERVER_CONNECTION);
// Configure callback when a correct connection with
// the Cloud Run server is established.
peer.on('open', (id) => {
console.log(`My peer ID is ${id}`);
});
您也可以允许用户定义自己的对等 ID,但应正确处理重复 ID。我建议你坚持使用随机 ID,它甚至可以是人类可读的。上述方法可让当前浏览器中的每个窗口都成为一个新的对等点。在某些浏览器中,可能无法使用加密 API,除非在安全环境(即启用 SSL 的网站)下工作。这就改变了你部署前端的方式,因为你应该使用 SSL。
创建对等对象的一部分工作是定义连接参数。请注意你是如何定义服务器密钥和服务器 URI 的。
有了对等对象后,就可以定义连接监听器,以便在 Peer JS 支持的任何连接事件上采取行动。您可以将它们定义为在事件触发后执行的函数。客户端代码将包含处理连接的所有逻辑,而 Peerserver 实例则是连接的中介。这里的部分工作是处理连接过程中可能出现的任何错误(这是非常容易出错的)。
// Start a connection on one end.
let conn = peer.connect('YOUR_DESTINATION_PEER');
conn.on('open', function() {
// Configure other connection listeners like send or
// received data using the conn object.
});
// Receive a connection on the other end.
peer.on('connection', (conn) => {
// Add connection listeners to the conn object.
});
请注意,连接的双方都应该有创建或接收连接的代码。这是因为两端都应能启动或接受连接。
有了连接侦听器后,只要知道其他对等节点的 ID,就可以与它们建立直接连接。具体方法是调用 connect 方法。请注意,这将在连接的接收端触发一个连接事件。
作为客户端实现的最后一部分,您必须能够使用对等对象提供的发送函数发送数据。
conn.send({
strings: 'hi!',
numbers: 150,
arrays: [1, 2, 3],
evenBinary: new Blob([1, 2, 3]),
andMore: { bool: true },
});
文档中的 Peer JS 教程有一个引人注目的 Peer JS 示例,可以帮助您开始学习。
实现对等查找
对等查询是不容忽视的一个方面。它为用户提供了良好的体验,因为他们可以轻松地建立远程连接。
实施这种查找有两个方面。一方面,你需要允许远程对等设备从服务器获取数据,比如对等设备列表。我们已经配置了 PeerJS 服务器的 Cloud Run 实例,以允许同行发现。它将在服务器上启用一个 /peers 路由,任何人都可以通过以下 URI 进行查询。
`https:// ${SERVER_URI} / ${SERVER_KEY} /peers`;
然后,您的客户端代码需要支持用户从服务器获取数据,并选择要连接到哪个对等体。
请注意,您可以自定义运行在 Peer JS 服务器中的逻辑,也就是说,您可以在服务器上做任何您想做的事情。但这需要构建自己的 Docker 镜像。
结束语
正如本文所概述的,在使用点对点连接时,物理服务器是一个关键的依赖因素。选择一个经济高效(或几乎免费)的托管解决方案对于初始测试和小规模项目非常重要。在转向更可定制的解决方案(如有必要)之前,GCP 中的云运行可以作为业余爱好或生产环境的重要选择。本文概述了仅部署解决方案后端部分的步骤,但仍有整个前端方面的内容。
你可以在点对点的终极井字游戏中前往我的 PeerJS 实现,并在线挑战你的朋友。
作者:Gonzalo Hirsch
原文:https://gonzalohirsch.com/blog/virtually-free-peer-js-server-on-gcp/
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/38715.html