dsh-agora 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/assets/agora/SKILL.md +113 -0
  4. package/assets/agora/references/cli/README.md +161 -0
  5. package/assets/agora/references/cli/automation.md +189 -0
  6. package/assets/agora/references/cli/doctor.md +129 -0
  7. package/assets/agora/references/cli/env.md +158 -0
  8. package/assets/agora/references/cli/install-auth.md +152 -0
  9. package/assets/agora/references/cli/projects.md +116 -0
  10. package/assets/agora/references/cli/quickstarts.md +117 -0
  11. package/assets/agora/references/cloud-recording/README.md +86 -0
  12. package/assets/agora/references/conversational-ai/README.md +285 -0
  13. package/assets/agora/references/conversational-ai/agent-client-toolkit-react.md +182 -0
  14. package/assets/agora/references/conversational-ai/agent-samples.md +101 -0
  15. package/assets/agora/references/conversational-ai/agent-toolkit-android.md +209 -0
  16. package/assets/agora/references/conversational-ai/agent-toolkit-ios.md +208 -0
  17. package/assets/agora/references/conversational-ai/agent-toolkit.md +201 -0
  18. package/assets/agora/references/conversational-ai/agent-ui-kit.md +63 -0
  19. package/assets/agora/references/conversational-ai/architecture.md +221 -0
  20. package/assets/agora/references/conversational-ai/auth-flow.md +154 -0
  21. package/assets/agora/references/conversational-ai/conversational-ai-studio.md +173 -0
  22. package/assets/agora/references/conversational-ai/go-sdk.md +184 -0
  23. package/assets/agora/references/conversational-ai/integration-from-quickstart.md +203 -0
  24. package/assets/agora/references/conversational-ai/python-sdk.md +122 -0
  25. package/assets/agora/references/conversational-ai/quickstarts.md +710 -0
  26. package/assets/agora/references/conversational-ai/server-custom-llm.md +45 -0
  27. package/assets/agora/references/conversational-ai/server-mcp.md +40 -0
  28. package/assets/agora/references/conversational-ai/server-sdk-rename.md +78 -0
  29. package/assets/agora/references/conversational-ai/server-sdks.md +128 -0
  30. package/assets/agora/references/doc-fetching.md +67 -0
  31. package/assets/agora/references/integration-patterns.md +201 -0
  32. package/assets/agora/references/mcp-tools.md +49 -0
  33. package/assets/agora/references/rtc/README.md +104 -0
  34. package/assets/agora/references/rtc/android.md +344 -0
  35. package/assets/agora/references/rtc/cross-platform-coordination.md +61 -0
  36. package/assets/agora/references/rtc/flutter.md +282 -0
  37. package/assets/agora/references/rtc/ios.md +306 -0
  38. package/assets/agora/references/rtc/nextjs.md +87 -0
  39. package/assets/agora/references/rtc/react-native.md +266 -0
  40. package/assets/agora/references/rtc/react.md +186 -0
  41. package/assets/agora/references/rtc/web.md +506 -0
  42. package/assets/agora/references/rtm/README.md +80 -0
  43. package/assets/agora/references/rtm/android.md +277 -0
  44. package/assets/agora/references/rtm/ios.md +231 -0
  45. package/assets/agora/references/rtm/web.md +348 -0
  46. package/assets/agora/references/server/README.md +22 -0
  47. package/assets/agora/references/server/tokens.md +74 -0
  48. package/assets/agora/references/server-gateway/README.md +80 -0
  49. package/assets/agora/references/server-gateway/linux-cpp.md +251 -0
  50. package/assets/agora/references/testing-guidance/SKILL.md +65 -0
  51. package/assets/agora/references/testing-guidance/completeness-gate.md +28 -0
  52. package/assets/agora/references/testing-guidance/convoai-rest.md +83 -0
  53. package/assets/agora/references/testing-guidance/mobile-rtm-and-renewal.md +109 -0
  54. package/assets/agora/references/testing-guidance/rtc-android.md +70 -0
  55. package/assets/agora/references/testing-guidance/rtc-ios.md +73 -0
  56. package/assets/agora/references/testing-guidance/rtc-react.md +51 -0
  57. package/assets/agora/references/testing-guidance/rtc-web.md +94 -0
  58. package/cordis.patch.yml +5 -0
  59. package/index.js +53 -0
  60. package/package.json +49 -0
@@ -0,0 +1,348 @@
1
+ # Agora Signaling SDK — Web (RTM)
2
+
3
+ ## Table of Contents
4
+
5
+ - [Overview](#overview)
6
+ - [Installation](#installation)
7
+ - [RTM v2 (Web)](#rtm-v2-web)
8
+ - [RTM v1 (Legacy Web)](#rtm-v1-legacy-web)
9
+ - [Common Use Cases with RTC](#common-use-cases-with-rtc)
10
+ - [Stream Channels (Topics)](#stream-channels-topics)
11
+
12
+ ## Overview
13
+
14
+ RTM provides signaling, text messaging, presence, and metadata capabilities alongside RTC audio/video. RTC and RTM are **independent systems** — RTC channels and RTM channels are separate namespaces.
15
+
16
+ **When to use RTM alongside RTC:**
17
+
18
+ - Text chat during video calls
19
+ - Signaling (call invitations, control messages)
20
+ - User presence/status tracking
21
+ - Custom data exchange (VAD signals, resolution requests)
22
+ - Sending text messages to AI agents (Conversational AI)
23
+
24
+ Package: `agora-rtm` (v2.x) on npm.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install agora-rtm
30
+ ```
31
+
32
+ ## RTM v2 (Web)
33
+
34
+ ### Initialization and Login
35
+
36
+ ```typescript
37
+ import AgoraRTM from "agora-rtm"
38
+
39
+ let rtmClient: AgoraRTM.RTM;
40
+ try {
41
+ rtmClient = new AgoraRTM.RTM("your-app-id", "user-id-string", {
42
+ logLevel: "debug", // "debug" | "info" | "warn" | "error"
43
+ });
44
+ } catch (status) {
45
+ console.error("RTM init failed", status);
46
+ }
47
+
48
+ // Always login with a server-generated RTM token
49
+ await rtmClient.login({ token: 'YOUR_RTM_TOKEN' })
50
+ ```
51
+
52
+ ### Channel Subscription
53
+
54
+ ```typescript
55
+ // Subscribe to a channel to receive messages and presence
56
+ await rtmClient.subscribe("channel-name", {
57
+ withMessage: true,
58
+ withPresence: true,
59
+ })
60
+
61
+ // Unsubscribe
62
+ await rtmClient.unsubscribe("channel-name")
63
+ ```
64
+
65
+ ### Sending Messages
66
+
67
+ ```typescript
68
+ // Publish to channel (all subscribers receive)
69
+ await rtmClient.publish("channel-name", "Hello everyone!", {
70
+ customType: "chat.message",
71
+ })
72
+
73
+ // Publish JSON data
74
+ await rtmClient.publish("channel-name", JSON.stringify({
75
+ type: "control",
76
+ action: "mute-all",
77
+ }), {
78
+ customType: "control.message",
79
+ })
80
+
81
+ // Peer-to-peer (publish to user topic)
82
+ await rtmClient.publish("target-user-id", JSON.stringify({
83
+ message: "Hello!",
84
+ priority: "APPEND",
85
+ }), {
86
+ customType: "user.transcription",
87
+ channelType: "USER",
88
+ })
89
+ ```
90
+
91
+ ### Receiving Messages
92
+
93
+ ```typescript
94
+ rtmClient.addEventListener("message", (event) => {
95
+ console.log("Message from:", event.publisher)
96
+ console.log("Channel:", event.channelName)
97
+ console.log("Content:", event.message) // string or Uint8Array
98
+ console.log("Type:", event.customType)
99
+
100
+ // Parse if JSON
101
+ if (typeof event.message === "string") {
102
+ try {
103
+ const data = JSON.parse(event.message)
104
+ } catch {}
105
+ }
106
+ })
107
+ ```
108
+
109
+ ### Presence Events
110
+
111
+ ```typescript
112
+ rtmClient.addEventListener("presence", (event) => {
113
+ // event.eventType: "SNAPSHOT" | "INTERVAL" | "JOIN" | "LEAVE" | "TIMEOUT" | "STATE_CHANGED"
114
+
115
+ switch (event.eventType) {
116
+ case "SNAPSHOT":
117
+ // Initial state on subscribe — event.snapshot is an array of {userId, states}
118
+ for (const user of event.snapshot) {
119
+ console.log("Online:", user.userId, user.states)
120
+ }
121
+ break
122
+ case "JOIN":
123
+ console.log("User joined:", event.publisher)
124
+ break
125
+ case "LEAVE":
126
+ case "TIMEOUT":
127
+ console.log("User left:", event.publisher)
128
+ break
129
+ case "INTERVAL":
130
+ // Periodic batch update — contains joinedUsers[], leftUsers[], timeoutUsers[]
131
+ for (const uid of event.joinedUsers ?? []) console.log("Joined:", uid)
132
+ for (const uid of event.leftUsers ?? []) console.log("Left:", uid)
133
+ break
134
+ case "STATE_CHANGED":
135
+ // User called setState — event.publisher, event.stateChanged (key-value pairs)
136
+ console.log("State changed:", event.publisher, event.stateChanged)
137
+ break
138
+ }
139
+ })
140
+ ```
141
+
142
+ ### Connection Status
143
+
144
+ ```typescript
145
+ rtmClient.addEventListener("status", (event) => {
146
+ // event.state: "CONNECTED" | "CONNECTING" | "RECONNECTING" | "DISCONNECTED"
147
+ console.log("RTM status:", event.state)
148
+ })
149
+ ```
150
+
151
+ ### Cleanup
152
+
153
+ ```typescript
154
+ async function cleanupRTM() {
155
+ await rtmClient.unsubscribe("channel-name")
156
+ await rtmClient.logout()
157
+ }
158
+ ```
159
+
160
+
161
+ ## Common Use Cases with RTC
162
+
163
+ ### Text Chat During Video Call
164
+
165
+ ```typescript
166
+ // RTM for chat alongside RTC video
167
+ rtmClient.addEventListener("message", (event) => {
168
+ if (event.customType === "chat.message") {
169
+ displayChatMessage(event.publisher, event.message)
170
+ }
171
+ })
172
+
173
+ function sendChatMessage(text: string) {
174
+ rtmClient.publish(channelName, text, { customType: "chat.message" })
175
+ }
176
+ ```
177
+
178
+ ### Voice Activity Detection (VAD) Signaling
179
+
180
+ ```typescript
181
+ // Notify other users when speaking (for prioritized video)
182
+ function notifyVAD(uid: number) {
183
+ rtmClient.publish(channelName, JSON.stringify({
184
+ type: "VAD",
185
+ uid: uid,
186
+ }), { customType: "signaling.vad" })
187
+ }
188
+ ```
189
+
190
+ ### Control Messages
191
+
192
+ ```typescript
193
+ // Request resolution change, stop screen share, etc.
194
+ rtmClient.publish(channelName, JSON.stringify({
195
+ type: "INCREASE_RESOLUTION",
196
+ targetUid: uid,
197
+ }), { customType: "signaling.control" })
198
+ ```
199
+
200
+ ### Sending Text to Conversational AI Agent
201
+
202
+ ```typescript
203
+ // Send a text message to an AI agent via RTM
204
+ async function sendMessageToAgent(message: string, agentUid: string) {
205
+ const publishTarget = `${agentUid}-${channel}`
206
+
207
+ await rtmClient.publish(publishTarget, JSON.stringify({
208
+ message: message.trim(),
209
+ priority: "APPEND", // or "REPLACE"
210
+ }), {
211
+ customType: "user.transcription",
212
+ channelType: "USER",
213
+ })
214
+ }
215
+ ```
216
+
217
+ ## Stream Channels (Topics)
218
+
219
+ Stream channels provide structured, topic-based messaging with lower latency than message channels. Users **join** a stream channel (rather than subscribing) and publish/subscribe to **topics** within it.
220
+
221
+ ```typescript
222
+ // Create and join a stream channel
223
+ const streamChannel = await rtmClient.createStreamChannel("channel-name")
224
+ await streamChannel.join({
225
+ token: "your-rtm-token", // or null for testing
226
+ withPresence: true,
227
+ })
228
+
229
+ // Join a topic to publish messages
230
+ await streamChannel.joinTopic("chat")
231
+
232
+ // Publish to a topic
233
+ await streamChannel.publishTopicMessage("chat", "Hello from stream channel!")
234
+
235
+ // Subscribe to a topic to receive messages from specific publishers (or all)
236
+ await streamChannel.subscribeTopic("chat", {
237
+ users: ["user-123", "user-456"], // optional: filter by publisher
238
+ })
239
+
240
+ // Receive messages (same "message" event as message channels)
241
+ rtmClient.addEventListener("message", (event) => {
242
+ console.log("Topic:", event.topicName, "From:", event.publisher, ":", event.message)
243
+ })
244
+
245
+ // Leave topic and channel
246
+ await streamChannel.leaveTopic("chat")
247
+ await streamChannel.leave()
248
+ ```
249
+
250
+ **When to use stream channels over message channels:**
251
+
252
+ - Lower latency needed (0.5s heartbeat vs 5s for message channels)
253
+ - Topic-based message routing within a channel
254
+ - Fine-grained publisher filtering per topic
255
+ - Max 64 users per stream channel, max 50 topics per channel
256
+
257
+ ## Presence State and Metadata
258
+
259
+ ### User State (setState / getState)
260
+
261
+ Set temporary key-value metadata on the current user that is broadcast to all subscribers:
262
+
263
+ ```typescript
264
+ // Set user state (visible to all channel subscribers)
265
+ await rtmClient.presence.setState("channel-name", "MESSAGE", {
266
+ displayName: "Alice",
267
+ status: "available",
268
+ typing: "false",
269
+ })
270
+
271
+ // Get a specific user's state
272
+ const result = await rtmClient.presence.getState("channel-name", "MESSAGE", "target-user-id")
273
+ console.log(result.states) // { displayName: "Alice", status: "available", ... }
274
+
275
+ // Remove state
276
+ await rtmClient.presence.removeState("channel-name", "MESSAGE", ["typing"])
277
+ ```
278
+
279
+ State is ephemeral — it is cleared when the user leaves or disconnects. Other users receive `STATE_CHANGED` presence events when state is updated.
280
+
281
+ ### Channel Metadata (Storage)
282
+
283
+ Store persistent metadata on a channel (survives user disconnect):
284
+
285
+ ```typescript
286
+ // Set channel metadata
287
+ const metadata = new AgoraRTM.Metadata()
288
+ metadata.setMetadataItem({ key: "roomTitle", value: "Team Standup" })
289
+ metadata.setMetadataItem({ key: "maxParticipants", value: "10" })
290
+ await rtmClient.storage.setChannelMetadata("channel-name", "MESSAGE", metadata, {})
291
+
292
+ // Get channel metadata
293
+ const result = await rtmClient.storage.getChannelMetadata("channel-name", "MESSAGE")
294
+ for (const item of result.metadata.items) {
295
+ console.log(item.key, item.value)
296
+ }
297
+
298
+ // Subscribe to metadata updates
299
+ await rtmClient.storage.subscribeChannelMetadata("channel-name", "MESSAGE")
300
+ rtmClient.addEventListener("storage", (event) => {
301
+ console.log("Metadata updated:", event.data)
302
+ })
303
+ ```
304
+
305
+ ### Important Notes
306
+
307
+ - RTM does **not** echo published messages back to the sender. Your chat UI must add sent messages locally.
308
+ - RTM uses **string UIDs** while RTC uses numeric UIDs. A common mapping strategy: use `String(rtcUid)` as the RTM userId, or maintain a lookup table if usernames differ.
309
+ - `presenceTimeout` can be configured during RTM initialization:
310
+
311
+ ```typescript
312
+ try {
313
+ const rtmClient = new AgoraRTM.RTM(appId, userId, {
314
+ presenceTimeout: 30, // seconds (5-1800), default 5
315
+ });
316
+ } catch (status) {
317
+ console.error("RTM init failed", status);
318
+ }
319
+ ```
320
+
321
+ ## Connection Management
322
+
323
+ ### Heartbeat Configuration
324
+
325
+ - **MESSAGE channels**: Heartbeat interval defaults to **5 seconds**, customizable from 5–1800 seconds via `presenceTimeout` config.
326
+ - **STREAM channels**: Fixed heartbeat interval of **0.5 seconds** (not configurable).
327
+ - Set `presenceTimeout` appropriately to prevent excessive presence event floods during brief network reconnections.
328
+
329
+ ### Connection Cleanup
330
+
331
+ - Always call `logout()` for MESSAGE channel connections.
332
+ - Always call `leave()` for STREAM channel connections before disconnecting.
333
+ - Failure to clean up properly causes ghost presence entries until heartbeat timeout.
334
+
335
+ ### REST API Rate Limiting
336
+
337
+ When using RTM REST APIs, implement exponential back-off on rate limit responses:
338
+
339
+ - 1st retry: wait **1 second**
340
+ - 2nd retry: wait **3 seconds**
341
+ - 3rd retry: wait **6 seconds**
342
+
343
+ ## Official Documentation
344
+
345
+ For APIs or features not covered above:
346
+
347
+ - API Reference: <https://docs.agora.io/en/signaling/reference/api?platform=web>
348
+ - Guides: <https://docs.agora.io/en/signaling/overview/product-overview>
@@ -0,0 +1,22 @@
1
+ # Agora Server-Side: Token Generation
2
+
3
+ Server-side token generation for Agora authentication.
4
+
5
+ ## When Tokens Are Needed
6
+
7
+ - **Production**: Always. Tokens authenticate users before they join channels.
8
+ - **Testing/Development**: Technically optional — token auth can be disabled in [Agora Console](https://console.agora.io), allowing `null` to be passed as the token. **Warn the user if they attempt this**: any channel can be joined by anyone without authentication. This is never acceptable for production and should be avoided even in development unless strictly necessary.
9
+ - **No App Certificate provided**: If the user has no App Certificate, they cannot generate tokens. Warn them explicitly that their project has no token security enabled, advise them to enable it in [Agora Console](https://console.agora.io) → Project Management → Edit → App Certificate, and do not proceed to generate code that omits token auth without this warning.
10
+ - **Never expose App Certificate on client**. Token generation must happen server-side.
11
+
12
+ ## Token Types
13
+
14
+ - **RTC Token**: Grants access to join a specific RTC channel with a specific UID. Required for Video/Voice SDK.
15
+ - **RTM Token**: Grants access to RTM services for a specific user ID.
16
+ - **AccessToken2**: Current token format. Supports privilege expiration per service and can bundle RTC + RTM privileges in a single token.
17
+
18
+ ## Reference Files
19
+
20
+ - **[tokens.md](tokens.md)** — Token generation for Node.js, Python, and Go. Express server example, security best practices.
21
+ - **Full token auth guide** — <https://docs-md.agora.io/en/video-calling/token-authentication/deploy-token-server.md>
22
+ - **Local credential export** — for development setup, use [../cli/env.md](../cli/env.md) to export or write App ID/App Certificate values with the Agora CLI. Never expose the App Certificate to client code.
@@ -0,0 +1,74 @@
1
+ # Agora Server-Side: Token Generation
2
+
3
+ ## Overview
4
+
5
+ Tokens authenticate users before joining channels. Generated server-side from App ID + App Certificate + channel + UID + expiration.
6
+
7
+ ## Quick Reference
8
+
9
+ - `onTokenPrivilegeWillExpire` fires **30 seconds** before expiry — renew proactively
10
+ - UID in token must match UID used to join
11
+ - Max token validity: 24 hours
12
+ - Use `RtcRole.SUBSCRIBER` for audience-only users (prevents stream bombing)
13
+
14
+ ## UID / Account-Name Constraints (Token Gotcha)
15
+
16
+ - Numeric UID (`buildTokenWithUid` + RTC join with numeric uid): must be `0` to `2^32 - 1`.
17
+ - String UID/account name (`buildTokenWithUserAccount` or `buildTokenWithRtm` account): ASCII only, max `255` characters.
18
+ - **RTM / `buildTokenWithRtm` `account`**: the API expects a string. Prefer an integer user id encoded as a string of digits (for example `"12345"`), not an arbitrary alphanumeric handle, to avoid identity clashes with other services.
19
+ - Here, `account` means the user's RTC identity string (account name), not your Agora customer account.
20
+ - Identity and type must match end-to-end:
21
+ - If the token is minted for numeric UID `123`, join RTC with numeric `123`.
22
+ - If the token is minted for account `"12345"` (string carrying a numeric id — preferred), join with that exact same string identity on the client; do not substitute a different handle or assume it interchangeably maps to a numeric uid unless your SDK documents that.
23
+
24
+ ## Token Generation Guides
25
+
26
+ - **[Deploy a Token Server](https://docs.agora.io/en/video-calling/token-authentication/deploy-token-server)** — Express/Flask/Go server examples
27
+ - **[Use Tokens](https://docs.agora.io/en/video-calling/token-authentication/authentication-workflow)** — When and how tokens are used
28
+
29
+ ## Token Libraries
30
+
31
+ All implementations are in [AgoraIO/Tools — DynamicKey/AgoraDynamicKey](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey):
32
+
33
+ | Language | Notes |
34
+ | -------- | ----------------------------------------------------------------------------------- |
35
+ | Node.js | Also available as [`agora-token`](https://www.npmjs.com/package/agora-token) on npm |
36
+ | Python 3 | Use `python3/` directory |
37
+ | Go | |
38
+ | Java | |
39
+ | C# | |
40
+ | Dart | |
41
+ | Deno | Native implementation — do NOT use the `agora-token` npm package in Deno |
42
+ | Rust | |
43
+ | PHP | |
44
+ | Ruby | |
45
+ | Lua | |
46
+ | Perl | |
47
+
48
+ ## Token Types
49
+
50
+ - **RTC Token** — channel access for Video/Voice SDK
51
+ - **RTM Token** — access for Real-Time Messaging
52
+ - **Combined RTC + RTM Token** — bundles RTC + RTM privileges in one token via `buildTokenWithRtm`; also satisfies the `agora token=` auth header for ConvoAI REST API calls (see [conversational-ai/README.md](../conversational-ai/README.md#authentication))
53
+
54
+ > **[AccessToken2 Guide](https://docs.agora.io/en/video-calling/token-authentication/deploy-token-server)** — AccessToken2 with multi-service privileges
55
+
56
+ ## buildTokenWithRtm (Node.js)
57
+
58
+ Generates a combined RTC + RTM token using `AccessToken2`. Use this when you need a single token that covers both channel access and RTM messaging — or to authenticate ConvoAI REST API calls.
59
+
60
+ ```javascript
61
+ import { RtcTokenBuilder, RtcRole } from 'agora-token';
62
+
63
+ const token = RtcTokenBuilder.buildTokenWithRtm(
64
+ appId, // string — your Agora App ID
65
+ appCertificate, // string — your App Certificate
66
+ channelName, // string — channel the user will join
67
+ account, // string — prefer integer user id as a string of digits (e.g. "12345")
68
+ RtcRole.PUBLISHER,
69
+ tokenExpire, // number — seconds until token expires (e.g. 3600)
70
+ privilegeExpire, // number — seconds until privileges expire (0 = same as tokenExpire)
71
+ );
72
+ ```
73
+
74
+ > **`account` vs `uid`**: `buildTokenWithRtm` takes a string `account`, not an integer type. Prefer passing the user's numeric id as a numeric string, and have the client join with that exact same string identity. If the RTC client joins with a numeric uid type instead, use `buildTokenWithUid` for RTC-only tokens.
@@ -0,0 +1,80 @@
1
+ # Agora Server Gateway SDK
2
+
3
+ Self-hosted SDK for transmitting audio and video streams between server-side applications and Agora's Voice and Video SDKs via the Agora SDRTN®.
4
+
5
+ ## Critical Rules
6
+
7
+ 1. **Video SDK channel must use `LIVE_BROADCASTING` mode** — standard `COMMUNICATION` mode is not supported when the remote peer is a Server Gateway client.
8
+ 2. **PCM audio must be sent in 10 ms intervals** — the SDK only accepts PCM frames of exactly 10 ms length.
9
+ 3. **AAC audio cannot use 44.1 kHz sampling** — use 16 kHz or 48 kHz instead.
10
+ 4. **All SDK methods are async and non-blocking** — use event callbacks and observers; do not expect synchronous results.
11
+ 5. **Server requires internet access to `*.agora.io` and `*.agoralab.co`** — ensure firewall rules allow outbound connections to these domains.
12
+ 6. **This is a self-hosted SDK, not a REST API** — the SDK runs as a process on your Linux server, not as a cloud service you call.
13
+
14
+ ## Key Concepts
15
+
16
+ - **IAgoraService** — root object. Create once per process, initialize with audio/video config before creating any connections.
17
+ - **IRtcConnection** — represents a connection to one RTC channel. Create one per channel. Manages join/leave lifecycle.
18
+ - **IMediaNodeFactory** — factory for creating senders and receivers (audio PCM sender, video YUV sender, encoded video sender, etc.).
19
+ - **Local tracks** — wrap senders/receivers and get published/subscribed via the connection.
20
+ - **Observers** — implement `ILocalUserObserver`, `IAudioFrameObserver`, `IVideoEncodedImageReceiver` to receive incoming media frames via callbacks.
21
+
22
+ ## Architecture
23
+
24
+ ```text
25
+ Your Server App (Server Gateway SDK)
26
+ ↕ audio/video frames (PCM, YUV, encoded)
27
+ Agora SDRTN® (global real-time network)
28
+
29
+ Video SDK clients (Web, iOS, Android, etc.)
30
+ ```
31
+
32
+ Typical flow:
33
+ 1. Initialize `IAgoraService` with audio/video support enabled
34
+ 2. Create `IRtcConnection` and join channel
35
+ 3. Create media senders via `IMediaNodeFactory`, wrap in local tracks, publish
36
+ 4. Register observers to receive incoming frames via callbacks
37
+ 5. On shutdown: unpublish → unregister observers → disconnect → release all objects (order matters)
38
+
39
+ ## Supported Platforms
40
+
41
+ | Platform | Language | Min OS |
42
+ |----------|----------|--------|
43
+ | Linux x86-64 | C++ | Ubuntu 14.04+ / CentOS 7.0+ |
44
+ | Linux x86-64 | Java | Ubuntu 14.04+ / CentOS 7.0+ |
45
+ | Linux x86-64 | Go | Ubuntu 18.04+ / CentOS 7.0+ |
46
+ | Linux x86-64 | Python | Ubuntu 18.04+ / CentOS 7.0+ |
47
+ | arm64 | C++ | Ubuntu 14.04+ |
48
+
49
+ Hardware minimum: 8-core CPU 1.8 GHz, 2 GB RAM (4 GB recommended).
50
+
51
+ ## Media Formats
52
+
53
+ | Type | Formats supported |
54
+ |------|------------------|
55
+ | Audio send | PCM (10 ms frames) |
56
+ | Audio receive | PCM |
57
+ | Video send | YUV, encoded (H.264, etc.) |
58
+ | Video receive | Encoded frames |
59
+
60
+ ## Use Cases
61
+
62
+ - **Call centers** — server-side agent voice processing
63
+ - **AI interactive classes** — server processes audio/video for AI analysis
64
+ - **Network testing** — automated stream injection and validation
65
+ - **aPaaS** — application platform integrations that need server-side media
66
+
67
+ ## Platform Reference Files
68
+
69
+ - **[linux-cpp.md](linux-cpp.md)** — C++ full implementation: init, senders, receivers, video mixing, shutdown sequence
70
+ - **Java, Go, Python** — Level 2 fetch required; use [../doc-fetching.md](../doc-fetching.md) or fetch directly from the links below
71
+
72
+ ## When to Fetch More
73
+
74
+ Always use Level 2 fetch for Java, Go, and Python quick-starts, SDK download links, and any platform-specific method signatures. Direct fallback URLs:
75
+
76
+ - **Java** — <https://docs-md.agora.io/en/server-gateway/get-started/integrate-sdk?platform=java.md>
77
+ - **Go** — <https://docs-md.agora.io/en/server-gateway/get-started/integrate-sdk?platform=go.md>
78
+ - **Python** — <https://docs-md.agora.io/en/server-gateway/get-started/integrate-sdk?platform=python.md>
79
+ - **Product Overview** — <https://docs-md.agora.io/en/server-gateway/overview/product-overview.md>
80
+ - **SDK Downloads** — <https://docs.agora.io/en/sdks>