客户端事件
客户端事件从一个已订阅的客户端直接传递到同一频道上的其他客户端。只有当你将后端订阅到 client-events webhook 分组时,后端才会收到副本。
客户端事件适用于输入指示器、光标位置或活动心跳等短暂信号。它们避免了通过 API 的往返。
不要将客户端事件用作权威状态。Realtime 边缘节点不会验证其载荷,因此接收方无法信任其内容。存储的聊天消息、状态变更和涉及权限的操作应通过你的服务器使用发布事件发送。
启用客户端事件
在 Realtime apps 页面为应用启用 Client Events。你也可以通过 Realtime API 将 client_events 设为 true。该设置作用于整个应用。在启用之前,Realtime 边缘节点会拒绝客户端事件。
客户端事件要求
Realtime 边缘节点强制执行三条规则:
- 名称必须以 client- 开头。 此保留前缀标识客户端事件。客户端会拒绝缺少该前缀的事件名称。
- 频道必须是私有或 presence 类型。 公共频道会被拒绝,这正是设计意图:应用密钥包含在你的页面中,任何人都可以订阅公共频道并向其写入。授权机制使客户端具备足够的可信度来广播消息,而只有私有频道和 presence 频道具备授权机制。
- 发送方必须已订阅。 连接必须已经加入它要触发事件的频道,因此客户端无法向它从未被准入的房间写入。
如果事件违反了其中任何一条规则,边缘节点会返回连接级别的错误。在开发过程中绑定该错误:
bird.connection.bind("error", (e) => console.warn("edge refused:", e.message));bird.onError { error in
print("edge refused:", error.message)
}bird.onError { error ->
println("edge refused: ${error.message}")
}发送
import { BirdRealtime } from "@messagebird/realtime";
const bird = new BirdRealtime({
appKey: "your-app-key",
region: "us1",
authEndpoint: "/bird/auth",
});
const room = bird.subscribe("presence-room-1");
input.addEventListener("input", () => {
room.trigger("client-typing", { at: Date.now() });
});let room = bird.subscribe("presence-room-1")
// From whatever your UI calls on a keystroke.
func typingChanged() throws {
guard room.subscribed else { return }
try room.trigger("client-typing", data: ["at": Date().timeIntervalSince1970])
}val room = bird.subscribe("presence-room-1")
// From whatever your UI calls on a keystroke.
fun typingChanged() {
if (!room.subscribed) return
room.trigger("client-typing", buildJsonObject { put("at", System.currentTimeMillis()) })
}可选的载荷可以是字符串、对象或数组。trigger 在发送帧后返回 true,如果频道未订阅则返回 false。要在加入后立即发送,请等待 bird:subscription_succeeded。
Swift 和 Kotlin 使用各自语言的 JSON 值作为载荷:在 Swift 中使用 Any? 并通过 JSONSerialization 编码,在 Kotlin 中使用 JsonElement。
接收
在同一频道上绑定你发送的事件名称,方式与服务器发布的事件完全相同:
room.bind("client-typing", (data) => showTypingIndicator(data));room.bind("client-typing") { data in
showTypingIndicator(data)
}room.bind("client-typing") { data ->
showTypingIndicator(data)
}发送方连接不会收到自己的事件。属于同一用户的其他连接会收到该事件,因此需要时请过滤这些副本。
请求速率限制
每个连接每秒最多可发送 10 个客户端事件。同一限制适用于应用上的每个连接。
当连接超过限制时,边缘节点会丢弃事件并报告错误,但不会关闭连接。绑定连接的 error 事件,并对光标移动等高频输入进行节流。
在服务器上接收客户端事件
要在服务器上接收客户端事件,请将端点订阅到 realtime.client_events 分组。每个 webhook 的 type 会在客户端事件名称前添加 realtime. 前缀,因此 client-typing 会变为 realtime.client-typing:
代码示例
{
"data": {
"channel_name": "presence-room-1",
"event": "client-typing",
"data": "{\"at\":1785495600000}",
"connection_id": "26896.319537",
"member_id": "u_42"
},
"timestamp": "2026-07-31T09:00:00Z",
"type": "realtime.client-typing"
}member_id 在 presence 频道中出现,在私有频道中不出现。光标位置等高频信号会为每个客户端事件生成一个 webhook。有关信封、签名和其他分组,请参阅 Realtime webhooks。
后续步骤
- Realtime webhooks 介绍如何在你自己的端点上接收客户端事件和频道活动。
- Presence 频道为客户端事件提供成员身份,以及用于渲染的成员列表。
- 发布事件是服务器端路径,用于处理不应信任客户端的所有操作。
相关资源
继续查阅此主题的文档、指南和示例。资源为英文。