发布事件
使用你的 Bird API 密钥以及 Realtime 应用的 key 和 secret 从服务器发布事件。切勿将应用 secret 包含在客户端代码中。若要让已订阅的客户端交换短暂信号,请在 private 或 presence 频道上使用客户端事件。
最简发布
事件需要一个名称和至少一个频道。可选的载荷可以包含任何 JSON 对象、数组或标量。
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({
apiKey: process.env.BIRD_API_KEY,
realtime: {
key: process.env.BIRD_REALTIME_KEY,
secret: process.env.BIRD_REALTIME_SECRET,
},
});
await bird.realtime.publish("rap_01krdgeqcxet5s7t44vh8rt9mg", {
event: "order-updated",
channels: ["orders"],
data: { id: 42, status: "shipped" },
});import os
from bird import Bird
client = Bird(
api_key=os.environ["BIRD_API_KEY"],
realtime_key=os.environ["BIRD_REALTIME_KEY"],
realtime_secret=os.environ["BIRD_REALTIME_SECRET"],
)
client.realtime.publish(
"rap_01krdgeqcxet5s7t44vh8rt9mg",
event="order-updated",
channels=["orders"],
data={"id": 42, "status": "shipped"},
)client, err := bird.NewClient(
option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
)
if err != nil {
log.Fatal(err)
}
_, err = client.Realtime.Publish(context.Background(), "rap_01krdgeqcxet5s7t44vh8rt9mg", bird.RealtimePublishParams{
Event: "order-updated",
Channels: []string{"orders"},
Data: map[string]any{"id": 42, "status": "shipped"},
})use MessageBird\Bird;
use MessageBird\RealtimeOptions;
use MessageBird\Wire\Model\RealtimePublish;
$bird = new Bird(
getenv('BIRD_API_KEY') ?: '',
realtime: new RealtimeOptions(
key: getenv('BIRD_REALTIME_KEY') ?: '',
secret: getenv('BIRD_REALTIME_SECRET') ?: '',
),
);
$bird->realtime->publish('rap_01krdgeqcxet5s7t44vh8rt9mg', (new RealtimePublish())
->setEvent('order-updated')
->setChannels(['orders'])
->setData(['id' => 42, 'status' => 'shipped']));curl -X POST https://us1.platform.bird.com/v1/realtime/apps/rap_01krdgeqcxet5s7t44vh8rt9mg/events \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "order-updated",
"channels": ["orders"],
"data": { "id": 42, "status": "shipped" }
}'在 orders 上绑定了 order-updated 的客户端会收到该事件。API 会拒绝以协议前缀 bird: 或 bird_internal: 开头的服务器发布事件名称。客户端发起的事件名称必须以 client- 开头。
完整的请求和响应(包括每个字段)见发布事件参考文档。
200 的含义
发布在 Realtime 边缘节点接受事件后即完成。投递是异步的,没有针对每个客户端的回执。在投递期间断开连接的客户端可能错过该事件,Realtime 不会在重新连接后重放该事件。
将持久状态存储在数据库中。使用事件通知变更,然后让客户端在重新连接后重新加载当前状态。
广播到多个频道
一次调用可以将同一事件发送到最多 100 个频道。private-encrypted- 频道在发布时必须是唯一的目标频道,因为每个加密频道使用不同的密钥。API 会以 E23000 拒绝加密频道的扇出请求。参见加密频道。
await bird.realtime.publish(appId, {
event: "price-changed",
channels: ["ticker-btc", "ticker-eth", "ticker-sol"],
data: { at: "2026-07-31T09:00:00Z" },
});client.realtime.publish(
app_id,
event="price-changed",
channels=["ticker-btc", "ticker-eth", "ticker-sol"],
data={"at": "2026-07-31T09:00:00Z"},
)_, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "price-changed",
Channels: []string{"ticker-btc", "ticker-eth", "ticker-sol"},
Data: map[string]any{"at": "2026-07-31T09:00:00Z"},
})$bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('price-changed')
->setChannels(['ticker-btc', 'ticker-eth', 'ticker-sol'])
->setData(['at' => '2026-07-31T09:00:00Z']));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "price-changed",
"channels": ["ticker-btc", "ticker-eth", "ticker-sol"],
"data": { "at": "2026-07-31T09:00:00Z" }
}'每个目标频道按一条独立消息计入用量。本示例计为三条消息。向 10,000 个用户专属频道发布因此计为 10,000 条消息。
批量发送不相关的事件
广播将一个事件发送到多个频道。批量请求在一次请求中发送最多 10 个不同的事件,每个事件发送到一个频道。
await bird.realtime.publishBatch(appId, {
events: [
{ event: "order-updated", channels: ["orders-42"], data: { status: "shipped" } },
{ event: "stock-changed", channels: ["inventory-99"], data: { left: 3 } },
],
});client.realtime.publish_batch(
app_id,
events=[
{"event": "order-updated", "channels": ["orders-42"], "data": {"status": "shipped"}},
{"event": "stock-changed", "channels": ["inventory-99"], "data": {"left": 3}},
],
)_, err := client.Realtime.PublishBatch(context.Background(), appID, bird.RealtimePublishBatchParams{
Events: []bird.RealtimeBatchEventParams{
{Event: "order-updated", Channel: "orders-42", Data: map[string]any{"status": "shipped"}},
{Event: "stock-changed", Channel: "inventory-99", Data: map[string]any{"left": 3}},
},
})$bird->realtime->publishBatch($appId, (new RealtimeBatchPublish())
->setEvents([
(new RealtimeBatchEvent())->setEvent('order-updated')->setChannel('orders-42')->setData(['status' => 'shipped']),
(new RealtimeBatchEvent())->setEvent('stock-changed')->setChannel('inventory-99')->setData(['left' => 3]),
]));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/batch-events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"events": [
{ "event": "order-updated", "channel": "orders-42", "data": { "status": "shipped" } },
{ "event": "stock-changed", "channel": "inventory-99", "data": { "left": 3 } }
]
}'使用批量请求将不相关的更新合并到一个请求中。每个事件仍单独计入用量,一次批量最多接受 10 个事件。参见批量发布。
排除触发操作的客户端
如果客户端已在本地应用了其操作,传入其连接 ID 以防止后续的发布再次应用相同的变更。边缘节点仅跳过该连接。
await bird.realtime.publish(appId, {
event: "message.created",
channels: ["presence-room-1"],
data: { body: "hello" },
exclude_connection_id: "26896.319537",
});client.realtime.publish(
app_id,
event="message.created",
channels=["presence-room-1"],
data={"body": "hello"},
exclude_connection_id="26896.319537",
)_, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "message.created",
Channels: []string{"presence-room-1"},
Data: map[string]any{"body": "hello"},
ExcludeConnectionID: "26896.319537",
})$bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('message.created')
->setChannels(['presence-room-1'])
->setData(['body' => 'hello'])
->setExcludeConnectionId('26896.319537'));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "message.created",
"channels": ["presence-room-1"],
"data": { "body": "hello" },
"exclude_connection_id": "26896.319537"
}'从客户端的当前连接中读取 ID,并将其包含在触发变更的请求中。其他标签页使用独立连接,仍会收到该事件。
在发布时读取频道状态
使用 include 在发布时返回每个目标频道的状态,从而避免单独的频道状态请求:
const result = await bird.realtime.publish(appId, {
event: "order-updated",
channels: ["presence-lobby"],
data: { id: 42 },
include: ["member_count", "connection_count"],
});result = client.realtime.publish(
app_id,
event="order-updated",
channels=["presence-lobby"],
data={"id": 42},
include=["member_count", "connection_count"],
)result, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "order-updated",
Channels: []string{"presence-lobby"},
Data: map[string]any{"id": 42},
Include: []bird.RealtimeChannelInclude{bird.RealtimeIncludeMemberCount, bird.RealtimeIncludeConnectionCount},
})$result = $bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('order-updated')
->setChannels(['presence-lobby'])
->setData(['id' => 42])
->setInclude(['member_count', 'connection_count']));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "order-updated",
"channels": ["presence-lobby"],
"data": { "id": 42 },
"include": ["member_count", "connection_count"]
}'member_count 仅适用于 presence 频道。connection_count 需要在应用上启用连接计数。请求这些属性会额外计为一条消息计入用量。
限制
| 限制项 | 值 |
|---|---|
| 每次发布的频道数 | 100 |
| 每次批量的事件数 | 10 |
| 事件载荷 | 序列化后 10 KB |
| 频道名称 | 164 个字符,包括字母、数字和 _ - = @ , . ; |
| 事件名称 | 200 个字符 |
超出任何限制会返回验证错误。API 不会截断请求。
安全重试
使用相同的 Idempotency-Key 重试发布以避免重复投递。TypeScript 和 Go SDK 会生成一个密钥并在自动重试时复用。如果你的应用自行重试请求,请提供并复用自己的密钥。参见幂等性。
后续步骤
- 频道授权是 private- 或 presence- 频道在客户端订阅前所需的步骤。
- Realtime 概述介绍了频道、成员和连接,以及用量的展示位置。
- 排除事件接收者防止触发操作的客户端收到自己的变更。
相关资源
继续查阅此主题的文档、指南和示例。资源为英文。