Skip to content

Commit 03e780b

Browse files
QizotCopilot
andauthored
FCE-2708 Adds docs for data channels (#219)
## Description This PR adds docs related to data channels in web sdk. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 0f3a84e commit 03e780b

8 files changed

Lines changed: 269 additions & 5 deletions

File tree

api/fishjam-server

docs/explanation/data-channels.mdx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
type: explanation
3+
sidebar_position: 7
4+
---
5+
6+
import Tabs from "@theme/Tabs";
7+
import TabItem from "@theme/TabItem";
8+
9+
# Data Channels
10+
11+
Data channels allow you to send and receive arbitrary binary data between peers in a room. This is useful for implementing features like text chat, file sharing, game state synchronization, or real-time cursor positions.
12+
13+
## Prerequisites
14+
15+
Before using data channels, you must be [connected to a room](../how-to/client/connecting). Data channels only work after you have successfully joined a room.
16+
17+
## Channel Types
18+
19+
The SDK provides two types of data channels, each optimized for different use cases:
20+
21+
### Reliable Channel
22+
23+
- **Ordered delivery**: Messages arrive in the order they were sent
24+
- **Guaranteed delivery**: All messages will be delivered, with automatic retransmission if needed
25+
- **Use cases**: Chat messages, file transfers, commands, or any data that must not be lost
26+
27+
### Lossy Channel
28+
29+
- **Unordered delivery**: Messages may arrive out of order
30+
- **No retransmission**: Messages may be dropped if the network is congested
31+
- **Lower latency**: Faster delivery since there's no waiting for retransmissions
32+
- **Use cases**: Real-time cursor positions, game state updates, live sensor data, or any data where the latest value matters more than every value
33+
34+
## Broadcast Communication
35+
36+
Data channels work in a **broadcast fashion** - when you publish data, it is sent to all other peers in the room. Additionally:
37+
38+
- Messages sent on the **reliable channel** are only received by peers subscribed to the **reliable channel**
39+
- Messages sent on the **lossy channel** are only received by peers subscribed to the **lossy channel**
40+
41+
This separation allows you to use both channels simultaneously for different purposes without interference.
42+
43+
## Using Data Channels
44+
45+
Use the [`useDataChannel`](../api/web/functions/useDataChannel) hook to work with data channels. The typical flow is:
46+
47+
1. Initialize the data channel after connecting to a room
48+
2. Subscribe to incoming messages
49+
3. Publish messages to other peers
50+
51+
For a complete step-by-step guide on implementing text chat, see [Text Chat](../how-to/features/text-chat).

docs/how-to/client/connecting.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,6 @@ Now that you're connected to a room, you can explore additional features:
168168

169169
- [Start Streaming](./start-streaming) - Enable your camera and microphone
170170
- [List Other Peers](./list-other-peers) - Display video from other participants
171+
- [Data Channels](../../explanation/data-channels) - Send and receive arbitrary data between peers (e.g., text chat)
171172
- [Picture in Picture](./picture-in-picture) - Allow users to watch video in a floating window (Mobile)
172173
- [Background Streaming](./background-streaming) - Keep calls active when the app is backgrounded (Mobile)

docs/how-to/features/text-chat.mdx

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
type: how-to
3+
title: Text Chat
4+
---
5+
6+
import Tabs from "@theme/Tabs";
7+
import TabItem from "@theme/TabItem";
8+
9+
# Text Chat
10+
11+
This guide shows how to implement text chat in your application using data channels. Data channels allow you to send and receive arbitrary binary data between peers in a room.
12+
13+
## Prerequisites
14+
15+
Before implementing text chat, you must be [connected to a room](../client/connecting). Data channels only work after you have successfully joined a room.
16+
17+
:::tip
18+
For a deeper understanding of how data channels work, including channel types and broadcast behavior, see [Data Channels](../explanation/data-channels).
19+
:::
20+
21+
---
22+
23+
## Step 1 — Set up the chat hook
24+
25+
Use the [`useDataChannel`](/api/web/functions/useDataChannel) hook to work with data channels. The typical flow is:
26+
27+
1. Initialize the data channel after connecting to a room
28+
2. Subscribe to incoming messages
29+
3. Publish messages to other peers
30+
31+
<Tabs groupId="platform">
32+
<TabItem value="web" label="React (Web)">
33+
34+
```tsx
35+
import { useConnection, useDataChannel } from "@fishjam-cloud/react-client";
36+
import { useCallback, useEffect, useState } from "react";
37+
38+
export function useChat() {
39+
const { peerStatus } = useConnection();
40+
const {
41+
initializeDataChannel,
42+
publishData,
43+
subscribeData,
44+
dataChannelReady,
45+
} = useDataChannel();
46+
47+
const [messages, setMessages] = useState<string[]>([]);
48+
49+
// Step 1: Initialize data channel when connected
50+
useEffect(() => {
51+
if (peerStatus === "connected") {
52+
initializeDataChannel();
53+
}
54+
}, [peerStatus, initializeDataChannel]);
55+
56+
// Step 2: Subscribe to incoming messages
57+
useEffect(() => {
58+
if (!dataChannelReady) return;
59+
60+
const unsubscribe = subscribeData(
61+
(data: Uint8Array) => {
62+
const message = new TextDecoder().decode(data);
63+
setMessages((prev) => [...prev, message]);
64+
},
65+
{ reliable: true },
66+
);
67+
68+
return unsubscribe;
69+
}, [subscribeData, dataChannelReady]);
70+
71+
// Step 3: Publish messages
72+
const sendMessage = useCallback(
73+
(text: string) => {
74+
if (!dataChannelReady) return;
75+
76+
const encoded = new TextEncoder().encode(text);
77+
publishData(encoded, { reliable: true });
78+
},
79+
[publishData, dataChannelReady],
80+
);
81+
82+
return { messages, sendMessage, ready: dataChannelReady };
83+
}
84+
```
85+
86+
</TabItem>
87+
<TabItem value="mobile" label="React Native (Mobile)" disabled>
88+
89+
Mobile SDK support for data channels will be available in a future release.
90+
91+
</TabItem>
92+
</Tabs>
93+
94+
---
95+
96+
## Step 2 — Use the chat hook in your component
97+
98+
Once you have the hook, you can use it in any component to send and display messages:
99+
100+
<Tabs groupId="platform">
101+
<TabItem value="web" label="React (Web)">
102+
103+
```tsx
104+
import React from "react";
105+
import { useConnection, useDataChannel } from "@fishjam-cloud/react-client";
106+
import { useCallback, useEffect, useState } from "react";
107+
108+
function useChat() {
109+
const { peerStatus } = useConnection();
110+
const {
111+
initializeDataChannel,
112+
publishData,
113+
subscribeData,
114+
dataChannelReady,
115+
} = useDataChannel();
116+
117+
const [messages, setMessages] = useState<string[]>([]);
118+
119+
useEffect(() => {
120+
if (peerStatus === "connected") {
121+
initializeDataChannel();
122+
}
123+
}, [peerStatus, initializeDataChannel]);
124+
125+
useEffect(() => {
126+
if (!dataChannelReady) return;
127+
128+
const unsubscribe = subscribeData(
129+
(data: Uint8Array) => {
130+
const message = new TextDecoder().decode(data);
131+
setMessages((prev) => [...prev, message]);
132+
},
133+
{ reliable: true },
134+
);
135+
136+
return unsubscribe;
137+
}, [subscribeData, dataChannelReady]);
138+
139+
const sendMessage = useCallback(
140+
(text: string) => {
141+
if (!dataChannelReady) return;
142+
143+
const encoded = new TextEncoder().encode(text);
144+
publishData(encoded, { reliable: true });
145+
},
146+
[publishData, dataChannelReady],
147+
);
148+
149+
return { messages, sendMessage, ready: dataChannelReady };
150+
}
151+
152+
// ---cut---
153+
154+
function ChatPanel() {
155+
const { messages, sendMessage, ready } = useChat();
156+
const [input, setInput] = useState("");
157+
158+
const handleSend = () => {
159+
if (input.trim()) {
160+
sendMessage(input);
161+
setInput("");
162+
}
163+
};
164+
165+
if (!ready) {
166+
return <div>Connecting to chat...</div>;
167+
}
168+
169+
return (
170+
<div>
171+
<div>
172+
{messages.map((msg: string, i: number) => (
173+
<div key={i}>{msg}</div>
174+
))}
175+
</div>
176+
<input
177+
value={input}
178+
onChange={(e) => setInput(e.target.value)}
179+
onKeyDown={(e) => e.key === "Enter" && handleSend()}
180+
/>
181+
<button onClick={handleSend}>Send</button>
182+
</div>
183+
);
184+
}
185+
```
186+
187+
</TabItem>
188+
<TabItem value="mobile" label="React Native (Mobile)" disabled>
189+
190+
Mobile SDK support for data channels will be available in a future release.
191+
192+
</TabItem>
193+
</Tabs>
194+
195+
---
196+
197+
## Why use the reliable channel?
198+
199+
For chat messages, we use `{ reliable: true }` because:
200+
201+
- **Ordered delivery**: Messages arrive in the order they were sent
202+
- **Guaranteed delivery**: All messages will be delivered, with automatic retransmission if needed
203+
204+
This ensures no chat messages are lost or arrive out of order.
205+
206+
---
207+
208+
## See also
209+
210+
- [Data Channels](../../explanation/data-channels) — detailed explanation of channel types and broadcast behavior
211+
- [Connecting to a room](../../how-to/client/connecting) — prerequisite for using data channels
212+
- [`useDataChannel` API reference](../../api/web/functions/useDataChannel)

packages/web-client-sdk

Submodule web-client-sdk updated 61 files

0 commit comments

Comments
 (0)