Publikowanie zdarzeń
Publikuj ze swojego serwera, używając klucza Bird API oraz klucza i sekretu aplikacji Realtime. Nigdy nie umieszczaj sekretu aplikacji w kodzie klienckim. Aby subskrybujący klienci mogli wymieniać krótkotrwałe sygnały, użyj zdarzeń klienckich na kanałach prywatnych lub presence.
Minimalne publikowanie
Zdarzenie wymaga nazwy i co najmniej jednego kanału. Opcjonalny ładunek może zawierać dowolny obiekt, tablicę lub skalar 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" }
}'Klienci nasłuchujący order-updated na orders otrzymują zdarzenie. API odrzuca nazwy publikowane z serwera, które zaczynają się od prefiksów protokołu bird: lub bird_internal:. Nazwy zdarzeń pochodzących od klienta muszą zaczynać się od client-.
Pełne żądanie i odpowiedź, wraz z każdym polem, znajdziesz w dokumentacji publikowania zdarzenia.
Co oznacza kod 200
Publikowanie kończy się, gdy węzeł brzegowy Realtime zaakceptuje zdarzenie. Dostarczanie jest asynchroniczne i nie ma potwierdzenia dla poszczególnych klientów. Klient, który rozłączy się w trakcie dostarczania, może nie otrzymać zdarzenia, a Realtime nie odtwarza go po ponownym połączeniu.
Przechowuj trwały stan w swojej bazie danych. Używaj zdarzeń do ogłaszania zmian, a po ponownym połączeniu każ klientom pobrać aktualny stan.
Rozsyłanie do wielu kanałów
Jedno wywołanie może wysłać to samo zdarzenie do maksymalnie 100 kanałów. Kanał private-encrypted- musi być jedynym kanałem w publikacji, ponieważ każdy szyfrowany kanał używa innego klucza. API odrzuca szyfrowane rozsyłanie z kodem E23000. Zobacz Kanały szyfrowane.
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" }
}'Każdy kanał docelowy liczy się jako osobna wiadomość w zużyciu. Ten przykład liczy się jako trzy wiadomości. Publikacja do 10 000 kanałów per użytkownik liczy się więc jako 10 000 wiadomości.
Grupowanie niepowiązanych zdarzeń
Rozsyłanie wysyła jedno zdarzenie do wielu kanałów. Batch wysyła do 10 różnych zdarzeń, każde do jednego kanału, w jednym żądaniu.
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 } }
]
}'Użyj batcha, aby połączyć niepowiązane aktualizacje w jedno żądanie. Każde zdarzenie nadal liczy się osobno w zużyciu, a batch przyjmuje maksymalnie 10 zdarzeń. Zobacz Publikowanie batcha.
Wykluczanie klienta, który wykonał akcję
Jeśli klient już zastosował swoją akcję lokalnie, przekaż jego identyfikator połączenia, aby wynikowa publikacja nie zastosowała tej samej zmiany ponownie. Węzeł brzegowy pomija tylko to połączenie.
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"
}'Odczytaj identyfikator z bieżącego połączenia klienta i dołącz go do żądania, które wyzwala zmianę. Inne karty korzystają z osobnych połączeń i nadal otrzymują zdarzenie.
Odczytywanie stanu kanału podczas publikowania
Użyj include, aby zwrócić stan każdego kanału docelowego w momencie publikacji i uniknąć osobnego żądania o stan kanału:
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 działa tylko na kanałach presence. connection_count wymaga zliczania połączeń w aplikacji. Żądanie tych atrybutów liczy się jako jedna dodatkowa wiadomość w zużyciu.
Limity
| Limit | Wartość |
|---|---|
| Kanały na publikację | 100 |
| Zdarzenia na batch | 10 |
| Ładunek zdarzenia | 10 KB po serializacji |
| Nazwa kanału | 164 znaki, litery, cyfry i _ - = @ , . ; |
| Nazwa zdarzenia | 200 znaków |
Przekroczenie dowolnego limitu zwraca błąd walidacji. API nie obcina żądania.
Bezpieczne ponawianie
Ponów publikację z tym samym Idempotency-Key, aby uniknąć podwójnego dostarczenia. SDK dla TypeScript i Go generują klucz i używają go ponownie przy automatycznych ponowieniach. Jeśli Twoja aplikacja ponawia żądanie, podaj i używaj ponownie własnego klucza. Zobacz Idempotentność.
Następne kroki
- Autoryzacja kanałów to to, czego kanał private- lub presence- potrzebuje, zanim klient będzie mógł subskrybować.
- Przegląd Realtime wyjaśnia kanały, członków i połączenia oraz gdzie widać zużycie.
- Wykluczanie odbiorców zdarzeń zapobiega otrzymaniu przez działającego klienta jego własnej zmiany.
Powiązane zasoby
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Poznaj możliwościRealtimePodążaj ścieżką naukiBuild your first integrationPrzewodnik wdrożeniowySend your first realtime event
Wypróbuj ćwiczenie i uzyskaj brief wdrożeniowy