频道在有订阅者时即刻存在,最后一个连接离开后随即消失。其名称决定类型:公共频道适用于访客可读的任何内容,私有频道适用于限定于某个客户的内容,在线状态频道用于带有成员列表的房间,缓存前缀则用于迟到的加入者需要立即获取的状态。
const bird = new BirdRealtime({ appKey: APP_KEY, region: "us1" });
// Public: anyone holding the app key can subscribe.
const scores = bird.subscribe("match-42");
// Private: your backend signs every subscription.
const order = bird.subscribe("private-order-ord_123");
// Presence: private, plus an identity the room can see.
const room = bird.subscribe("presence-room-42");
// Cache: the latest event replays to whoever joins next.
const build = bird.subscribe("cache-build-8821");
build.bind("bird:cache_miss", () => showSkeleton());
前缀即配置。
无需维护频道注册表。
频道是 Bird Realtime API 的寻址模型。您无需创建频道:只需订阅一个名称,名称的前几个字符会告诉边缘节点如何处理它。没有前缀的名称为公共频道。private- 要求您的后端审批每个订阅。presence- 同样需要审批,并附加身份信息。private-encrypted- 使用 Bird 永远不会持有的密钥加密负载。名称最长 164 个字符,区分大小写,是频道中唯一需要仔细考虑的部分,因为公共名称对任何持有应用密钥的人可见。
五种房间类型。
相同的协议、相同的客户端、相同的发布调用。区别仅在于名称。
- 01
公共频道。
无需授权端点,无需注册。任何持有应用密钥的人都可以订阅,这使其非常适合构建结果、实时比分、航班信息或状态页面,但不适合限定于单个客户的内容。不要在名称中包含标识符:orders 不会泄露任何信息,orders-user-4821 则会暴露用户 4821 的存在。
- 02
私有频道。
private- 名称会将订阅路由到您自己的端点,该端点检查会话并使用应用密钥对连接 ID 和频道名称进行签名。您的规则、您的会话、您的 403。边缘节点验证签名,未经验证的内容不会到达频道。
- 03
在线状态频道。
在私有频道授权基础上增加身份信息,因此每个订阅者都能获取成员列表,并收到加入和离开的通知。这是唯一带有成员花名册的频道类型。
- 04
加密频道。
private-encrypted- 频道承载由您的服务器使用 32 字节主密钥加密的负载,该密钥永远不会出现在 Realtime 请求中。边缘节点及其与浏览器之间的所有节点看到的都是密文。频道和事件名称保持明文,因此请选择不会泄露您所保护内容的名称。
- 05
缓存频道。
在任何类型前缀之后,以 cache- 开头命名,频道将记住最近一次通过 API 发布的事件,并向每个新订阅者重放。订阅同时充当初始状态获取。有两个值得在设计中考虑的约束:仅保留最近一条事件,且可能在 30 分钟上限之前过期,因此请在每个负载中放入完整状态,并通过缓存未命中 webhook 重新填充,而不是假设缓存始终有效。
一次发布,最多一百个频道。
发布是来自您服务器的普通 REST 调用。在一个请求中指定最多 100 个频道,边缘节点会将事件分发到所有频道。一个批次可携带最多 10 个不相关的事件,每个事件发往各自的频道。传入操作客户端的连接 ID 作为 exclude_connection_id,已在本地应用更改的标签页将被跳过。在 include 中请求连接数或成员数,响应会告诉您发布时每个频道的状态。使用相同的幂等键重试,不会重复投递。
// One event, up to 100 channels, one request.
const result = await bird.realtime.publish(APP_ID, {
event: "score-updated",
channels: ["match-42", "cache-match-42"],
data: { home: 2, away: 1 },
// The tab that scored already rendered it locally.
exclude_connection_id: "26896.319537",
include: ["connection_count"],
});
for (const channel of result.data ?? []) {
console.log(channel.name, channel.connection_count);
}
客户端可以直接相互通信。
输入指示器或光标位置不需要经过您的 API。在应用上启用客户端事件,已订阅的客户端可以直接向频道中的其他成员触发名为 client-something 的事件,每个连接每秒上限 10 次。它们仅在私有和在线状态频道上有效,这是有意为之的:应用密钥包含在您的页面中,因此授权是让客户端可信到足以广播的保障。将收到的内容视为信号,而非权威状态,因为边缘节点不会验证负载。
频道会记住什么,不会记住什么。
发布在边缘节点接受事件后即返回。投递是异步的,没有逐客户端回执,投递过程中断开的客户端在重连后不会再收到该事件。这是诚实的契约,也是为什么持久状态应存储在您的数据库中,而事件只是通知状态已变更。所有套餐的上限相同:每次发布 100 个频道、每批 10 个事件、每个负载 10 KB、频道名称 164 个字符。
在文档中深入了解。
Realtime 概览在一个页面中定义了频道、成员和连接。发布事件涵盖广播、批量和排除,缓存频道解释了重放机制,查询频道状态是服务端用于获取在线人数和计数的读取接口。
付诸实践。
继续查阅此主题的文档、指南和示例。资源为英文。