INTEGRITY Dokumentace

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

  1. Vytvořte relaci Realtime pro vydavatele a jednu pro každého odběratele.
  2. 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).
  3. V relaci publikujícího vytvořte pojmenovaný DataChannel pomocí POST /apps/{appId}/sessions/{sessionId}/datachannels/new a nastavte location na "local".
  4. V každé relaci odběratele zavolejte stejný endpoint s location nastaveno na "remote". Nastavte sessionId k ID relace publikujícího a použijte stejné dataChannelName.
  5. V každém klientovi zavolejte createDataChannel() hodnotou negotiated: true a ID vráceným API.
  6. 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:

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ý.

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ě:

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:

  1. U publikujícího vytvořte lokální DataChannel s názvem my-channel.
  2. U odběratele načtěte DataChannel pomocí canReply: true a otevřete vyjednaný kanál v prohlížeči.
  3. Z vydavatele odešlete zprávu odběrateli.
  4. 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.