← Cloudflare Realtime / realtime / sfu
DataChannels
Pomocí DataChannels Realtime SFU odesílejte data aplikace s nízkou latencí přes WebRTC. Mezi běžné payloady patří chatové zprávy, stav hry, aktualizace senzorů a řídicí události.
Pro odesílání zvuku a videa použijte mediální tracky Realtime SFU, nikoli DataChannels.
graph LR
A[Publisher] -->|Application data| B[Cloudflare Realtime SFU]
B -->|Application data| C@{ shape: procs, label: "Subscribers"}
Publisher může odeslat pojmenovaný DataChannel více subscriberům. Zprávy standardně proudí od publishera k subscriberům.
Nastavte DataChannel
- Vytvořte relaci Realtime pro vydavatele a jednu pro každého odběratele.
- V každé relaci vytvořte přenos DataChannel pomocí
POST /apps/{appId}/sessions/{sessionId}/datachannels/establish. Před vytvořením kanálů dokončete veškerou požadovanou výměnu Session Description Protocol (SDP). - V relaci publikujícího vytvořte pojmenovaný DataChannel pomocí
POST /apps/{appId}/sessions/{sessionId}/datachannels/newa nastavtelocationna"local". - V každé relaci odběratele zavolejte stejný endpoint s
locationnastaveno na"remote". NastavtesessionIdk ID relace publikujícího a použijte stejnédataChannelName. - V každém klientovi zavolejte
createDataChannel()hodnotounegotiated: truea ID vráceným API. - Jakmile se DataChannels otevřou, odešlete zprávy od publishera.
Konfigurovat doručování zpráv
DataChannels ve výchozím nastavení používají spolehlivé a seřazené doručování. Zvolte částečnou spolehlivost nebo doručování bez zachování pořadí v situacích, kdy je aktuálnost dat důležitější než jejich opožděné doručení bez ztráty, například u stavu hry nebo dat ze senzorů v reálném čase.
Nastavte tato volitelná pole při vytváření DataChannel pomocí HTTPS API:
ordered(boolean, výchozítrue): nastavte nafalsea povolíte tak, aby zprávy mohly přicházet mimo pořadí. Zpožděná zpráva nezablokuje pozdější zprávy.maxRetransmits(integer): omezuje počet pokusů o opětovné odeslání po prvním odeslání. Nastavte na0pro žádné opakované přenosy, nebo tuto hodnotu vynechte, pokud nemá být limit opakovaných přenosů žádný.maxPacketLifeTime(integer): omezuje, jak dlouho (v milisekundách) se transport pokouší o doručení. Pokud nechcete limit životnosti nastavit, parametr vynechte.
maxRetransmits a maxPacketLifeTime se vzájemně vylučují. Nenastavujte obě na stejném kanálu.
Chování řazení a opakování pokusů je nezávislé. Pro spolehlivé doručení bez zachování pořadí nastavte ordered: false a vynechte obě maxRetransmits a maxPacketLifeTime. Zprávy mohou dorazit v jiném pořadí, transportní vrstva ale neúspěšná doručení dál opakuje.
Použijte stejné hodnoty u vydavatele (location: "local"), každý odběratel (location: "remote"), a každého klienta createDataChannel() volání. Realtime DataChannels používají vyjednaná ID, takže prohlížeč tato nastavení od vzdáleného peeru nezískává.
Vytvoření nespolehlivého, neuspořádaného kanálu vydavatele:
{
"dataChannels": [
{
"location": "local",
"dataChannelName": "player-state",
"ordered": false,
"maxRetransmits": 0
}
]
}Poté na straně subscriberu vytvořte odpovídající vzdálený kanál se stejnými poli spolehlivosti:
{
"dataChannels": [
{
"location": "remote",
"sessionId": "<PUBLISHER_SESSION_ID>",
"dataChannelName": "player-state",
"ordered": false,
"maxRetransmits": 0
}
]
}Vytvořte odpovídající DataChannel v prohlížeči se stejným nastavením. V tomto příkladu pc je aktivní RTCPeerConnection, a resp je odpověď API pro kanál.
const dc = pc.createDataChannel("player-state", {
negotiated: true,
id: resp.dataChannels[0].id,
ordered: false,
maxRetransmits: 0,
});Pro částečnou spolehlivost zvolte limit opakovaných přenosů nebo dobu života paketu podle toho, jak dlouho zůstává payload užitečný.
Čekání na připravenost odběratele (waitForAck)
Nastavte waitForAck: true na vzdáleném DataChannel a zpozdí doručení, dokud odběratel nesignalizuje, že je připravený.
waitForAckse vztahuje pouze nalocation: "remote"DataChannels a výchozí hodnota jefalse.- Dokud je brána zavřená, SFU pozastaví doručování danému odběrateli.
- Jakmile se DataChannel otevře, odběratel odešle libovolnou zprávu, například
"ack". SFU zpracuje tuto první zprávu, otevře bránu a začne přeposílat zprávy vydavatele. - Potvrzení musí dorazit k SFU do 30 sekund od vytvoření vzdáleného DataChannel. Jinak SFU uzavře zablokovaný kanál. Pro opakování vytvořte vzdálený DataChannel znovu.
Bez canReply, zprávy pozdějších odběratelů se vydavateli nepředávají.
Vytvořte vzdálený DataChannel s povolenou bránou zavoláním POST /apps/{appId}/sessions/{sessionId}/datachannels/new na relaci odběratele:
{
"dataChannels": [
{
"location": "remote",
"sessionId": "<PUBLISHER_SESSION_ID>",
"dataChannelName": "my-channel",
"waitForAck": true
}
]
}Poté na straně subscriberu odešlete potvrzení, jakmile se DataChannel otevře. Tento příklad předpokládá, že jste inicializovali API_BASE, headers, a pc, a definovali waitForOpen() pomocnou funkci.
const response = await fetch(
`${API_BASE}/sessions/${subscriberId}/datachannels/new`,
{
method: "POST",
headers,
body: JSON.stringify({
dataChannels: [
{
location: "remote",
sessionId: publisherId,
dataChannelName: "my-channel",
waitForAck: true,
},
],
}),
},
);
if (!response.ok) {
throw new Error(`Failed to create DataChannel: ${response.status}`);
}
const resp = await response.json();
const channelId = resp.dataChannels?.[0]?.id;
if (channelId === undefined) {
throw new Error("DataChannel response did not include an id");
}
const dc = pc.createDataChannel("my-channel-subscribed", {
negotiated: true,
id: channelId,
});
await waitForOpen(dc);
dc.send("ack"); // The first message opens the gate.Návrat k vydavateli (canReply)
Zprávy standardně putují od publishera k subscriberům. Nastavte canReply: true když potřebuje jeden odběratel odpovědět na stejném kanálu, například když operátor odpovídá zařízení, které publikuje telemetrii.
graph LR
P[Publisher] -->|Publisher messages| SFU[Cloudflare Realtime SFU]
SFU -->|Publisher messages| S1[Subscriber with canReply]
SFU -->|Publisher messages| S2[Other subscribers]
S1 -->|Reply| SFU
SFU -->|Reply| P
canReply řídí přístup k odpovědím následovně:
canReplyse vztahuje pouze nalocation: "remote"DataChannels a výchozí hodnota jefalse.- Přístup k odpovědi pro každý DataChannel vydavatele může mít nejvýše jeden odběratel. Udělení přístupu jinému odběrateli nahradí předchozího odběratele.
- SFU předává odpovědi pouze od odběratele, který má přístup.
- Odpovědi dostává publisher. Ostatní subscribeři je nedostávají.
Povolit odpovědi při přihlašování k odběru
Vytvořte vzdálený DataChannel v relaci odběratele pomocí canReply: true:
{
"dataChannels": [
{
"location": "remote",
"sessionId": "<PUBLISHER_SESSION_ID>",
"dataChannelName": "my-channel",
"canReply": true
}
]
}Ukázkový postup:
- U publikujícího vytvořte lokální DataChannel s názvem
my-channel. - U odběratele načtěte DataChannel pomocí
canReply: truea otevřete vyjednaný kanál v prohlížeči. - Z vydavatele odešlete zprávu odběrateli.
- Z odběratele odpovězte na stejném kanálu. Vydavatel odpověď obdrží.
Změnit přístup k odpovědím
Chcete-li změnit přístup k odpovídání bez opětovného vytváření vzdáleného DataChannel, zavolejte PUT /apps/{appId}/sessions/{subscriberSessionId}/datachannels/update:
{
"dataChannels": [
{
"location": "remote",
"sessionId": "<PUBLISHER_SESSION_ID>",
"dataChannelName": "my-channel",
"canReply": true
}
]
}Použijte stejné tělo s "canReply": false ke zrušení. Následující tabulka uvádí běžné vzory:
| Cíl | Akce |
|---|---|
| Povolit odpovědi po přihlášení k odběru | Vytvořte vzdálený DataChannel bez canReply, poté jej aktualizujte pomocí canReply: true. |
| Přesunutí přístupu na jiného subscribera | U nového odběratele aktualizujte DataChannel pomocí canReply: true. Předchozí odběratel ztrácí přístup k odpovídání. |
| Zastavit odpovídání | U odběratele s přístupem k odpovědi aktualizujte DataChannel pomocí canReply: false. |
// The subscriber already pulled "my-channel" without canReply.
// Allow replies later.
const response = await fetch(
`${API_BASE}/sessions/${subscriberId}/datachannels/update`,
{
method: "PUT",
headers,
body: JSON.stringify({
dataChannels: [
{
location: "remote",
sessionId: publisherId,
dataChannelName: "my-channel",
canReply: true,
},
],
}),
},
);
if (!response.ok) {
throw new Error(`Failed to update DataChannel: ${response.status}`);
}
// The same negotiated DataChannel can now send replies to the publisher.
dc.send(JSON.stringify({ type: "reply", body: "pong" }));Kombinovat potvrzení a odpovědi
Můžete nastavit obě canReply a waitForAck na stejném vzdáleném DataChannel. První zpráva odběratele otevře potvrzovací bránu a není přeposlána. Následné zprávy odběratele jsou přeposílány vydavateli, dokud má daný odběratel přístup k odpovědi.
Příklad
Zkontrolujte Příklad echo pro DataChannel ↗ pro kompletní nastavení přenosu, publikování a odběru.
Příklad umisťuje token aplikace do kódu prohlížeče pro místní testování. V produkčním prostředí token uchovávejte na backendu.