Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar visibility is curated in lib/docs/audience-curated-docs.ts.
Ring messenger can place 1:1 audio and video calls inside a direct conversation. Signaling rides the existing Tunnel channel conversation:{id}. Media uses the browser RTCPeerConnection. NAT traversal uses STUNner (STUN/TURN) on the cluster, with ICE servers delivered by an authenticated API — credentials never ship in NEXT_PUBLIC_*.
| Layer | Role |
|---|---|
| UI | Phone / Video on conversation header → full-screen call overlay |
| Signaling | Tunnel events call:invite … call:hangup on conversation:{id} |
| ICE | GET /api/webrtc/ice-servers (session required) |
| TURN | STUNner Gateway TURN-UDP:3478 (e.g. turn.ring-platform.org) |
Related: Messaging · Tunnel Protocol · Real-time architecture
Members close deals faster when they can talk without leaving your Ring. Calls stay inside the same conversation that already carries opportunity, entity, or store context.
Conversations, groups, and Tunnel live chat.
The realtime pipe calls reuse for invite / accept / hangup.
Where STUNner and env wiring live for k8s clones.
stunner-system) and Gateway programmed in namespace stunner.Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar visibility is curated in lib/docs/audience-curated-docs.ts.
Ring messenger can place 1:1 audio and video calls inside a direct conversation. Signaling rides the existing Tunnel channel conversation:{id}. Media uses the browser RTCPeerConnection. NAT traversal uses STUNner (STUN/TURN) on the cluster, with ICE servers delivered by an authenticated API — credentials never ship in NEXT_PUBLIC_*.
| Layer | Role |
|---|---|
| UI | Phone / Video on conversation header → full-screen call overlay |
| Signaling | Tunnel events call:invite … call:hangup on conversation:{id} |
| ICE | GET /api/webrtc/ice-servers (session required) |
| TURN | STUNner Gateway TURN-UDP:3478 (e.g. turn.ring-platform.org) |
Related: Messaging · Tunnel Protocol · Real-time architecture
Members close deals faster when they can talk without leaving your Ring. Calls stay inside the same conversation that already carries opportunity, entity, or store context.
Conversations, groups, and Tunnel live chat.
The realtime pipe calls reuse for invite / accept / hangup.
Where STUNner and env wiring live for k8s clones.
stunner-system) and Gateway programmed in namespace stunner.Use Founder / Developer tabs in the docs sidebar to filter this page. Sidebar visibility is curated in lib/docs/audience-curated-docs.ts.
Ring messenger can place 1:1 audio and video calls inside a direct conversation. Signaling rides the existing Tunnel channel conversation:{id}. Media uses the browser RTCPeerConnection. NAT traversal uses STUNner (STUN/TURN) on the cluster, with ICE servers delivered by an authenticated API — credentials never ship in NEXT_PUBLIC_*.
| Layer | Role |
|---|---|
| UI | Phone / Video on conversation header → full-screen call overlay |
| Signaling | Tunnel events call:invite … call:hangup on conversation:{id} |
| ICE | GET /api/webrtc/ice-servers (session required) |
| TURN | STUNner Gateway TURN-UDP:3478 (e.g. turn.ring-platform.org) |
Related: Messaging · Tunnel Protocol · Real-time architecture
Members close deals faster when they can talk without leaving your Ring. Calls stay inside the same conversation that already carries opportunity, entity, or store context.
Conversations, groups, and Tunnel live chat.
The realtime pipe calls reuse for invite / accept / hangup.
Where STUNner and env wiring live for k8s clones.
stunner-system) and Gateway programmed in namespace stunner.turn.ring-platform.org A/AAAA → node LB IP).WEBRTC_STUN_URL, WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, WEBRTC_TURN_CREDENTIAL.Calls require a live Tunnel session. If realtime is disconnected, the UI refuses to start a call — fix Tunnel first (Tunnel Protocol).
features/messages/components/messages-shell.tsx| Wires hook + overlay |
infrastructure/k3s-or/stunner/ | GatewayClass, GatewayConfig, Gateway manifests |
k8s/ENV-PROD-WIRING.md | Prod env table for WEBRTC_* |
GET /api/webrtc/ice-servers — requires Auth.js session (401 if anonymous).
Response shape (verified):
STUN falls back to stun:stun.l.google.com:19302 when WEBRTC_STUN_URL is unset. TURN is added only when all of WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, and WEBRTC_TURN_CREDENTIAL are set.
| Variable | Where | Notes |
|---|---|---|
WEBRTC_STUN_URL | ConfigMap | Optional; Google STUN default in route |
WEBRTC_TURN_URL | ConfigMap | e.g. turn:turn.ring-platform.org:3478?transport=udp |
WEBRTC_TURN_USERNAME | Secret ring-platform-org-secrets | Matches STUNner auth Secret |
WEBRTC_TURN_CREDENTIAL | Secret | Never NEXT_PUBLIC_* |
Examples: k8s/secrets.example.yaml, wiring notes: k8s/ENV-PROD-WIRING.md.
env.local.template does not yet list these keys — use the k8s examples for local/prod parity.
Published on channel conversation:{conversationId} (same channel as typing):
| Event | Purpose |
|---|---|
call:invite | Outgoing ring |
call:accept / call:reject | Callee decision |
call:offer / call:answer | SDP |
call:ice | ICE candidates |
call:hangup | Tear down |
Subscribe with useTunnelChannel — do not raw-subscribe in effects (Tunnel Protocol).
Install operator (pulls Gateway API + STUNner CRDs):
Create auth Secret (type=static, username, password) and apply infrastructure/k3s-or/stunner/gateway.yaml (GatewayClass + GatewayConfig + Gateway with protocol TURN-UDP).
Wire app Secret/ConfigMap + ensure Deployment env refs for WEBRTC_TURN_USERNAME / WEBRTC_TURN_CREDENTIAL (k8s/deployment.yaml). Restart the app Deployment.
Smoke: external STUN Binding to :3478; authenticated GET /api/webrtc/ice-servers; two browsers on the same direct conversation.
Listener protocol must be TURN-UDP, not bare UDP. Realm in GatewayConfig is alphanumeric + hyphen (e.g. ring-platform-org). Empty UDPRoute backendRefs are invalid — peer TURN does not need a UDPRoute until an SFU (LiveKit) exists.
Connect Platform’s RTVS / FastTransponder stack is not ported — only control UX patterns (mute / camera / end) were absorbed.
{
"success": true,
"data": {
"iceServers": [
{ "urls": "stun:…" },
{ "urls": "turn:…", "username": "…", "credential": "…" }
],
"turnConfigured": true
}
}turn.ring-platform.org A/AAAA → node LB IP).WEBRTC_STUN_URL, WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, WEBRTC_TURN_CREDENTIAL.Calls require a live Tunnel session. If realtime is disconnected, the UI refuses to start a call — fix Tunnel first (Tunnel Protocol).
features/messages/components/messages-shell.tsx| Wires hook + overlay |
infrastructure/k3s-or/stunner/ | GatewayClass, GatewayConfig, Gateway manifests |
k8s/ENV-PROD-WIRING.md | Prod env table for WEBRTC_* |
GET /api/webrtc/ice-servers — requires Auth.js session (401 if anonymous).
Response shape (verified):
STUN falls back to stun:stun.l.google.com:19302 when WEBRTC_STUN_URL is unset. TURN is added only when all of WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, and WEBRTC_TURN_CREDENTIAL are set.
| Variable | Where | Notes |
|---|---|---|
WEBRTC_STUN_URL | ConfigMap | Optional; Google STUN default in route |
WEBRTC_TURN_URL | ConfigMap | e.g. turn:turn.ring-platform.org:3478?transport=udp |
WEBRTC_TURN_USERNAME | Secret ring-platform-org-secrets | Matches STUNner auth Secret |
WEBRTC_TURN_CREDENTIAL | Secret | Never NEXT_PUBLIC_* |
Examples: k8s/secrets.example.yaml, wiring notes: k8s/ENV-PROD-WIRING.md.
env.local.template does not yet list these keys — use the k8s examples for local/prod parity.
Published on channel conversation:{conversationId} (same channel as typing):
| Event | Purpose |
|---|---|
call:invite | Outgoing ring |
call:accept / call:reject | Callee decision |
call:offer / call:answer | SDP |
call:ice | ICE candidates |
call:hangup | Tear down |
Subscribe with useTunnelChannel — do not raw-subscribe in effects (Tunnel Protocol).
Install operator (pulls Gateway API + STUNner CRDs):
Create auth Secret (type=static, username, password) and apply infrastructure/k3s-or/stunner/gateway.yaml (GatewayClass + GatewayConfig + Gateway with protocol TURN-UDP).
Wire app Secret/ConfigMap + ensure Deployment env refs for WEBRTC_TURN_USERNAME / WEBRTC_TURN_CREDENTIAL (k8s/deployment.yaml). Restart the app Deployment.
Smoke: external STUN Binding to :3478; authenticated GET /api/webrtc/ice-servers; two browsers on the same direct conversation.
Listener protocol must be TURN-UDP, not bare UDP. Realm in GatewayConfig is alphanumeric + hyphen (e.g. ring-platform-org). Empty UDPRoute backendRefs are invalid — peer TURN does not need a UDPRoute until an SFU (LiveKit) exists.
Connect Platform’s RTVS / FastTransponder stack is not ported — only control UX patterns (mute / camera / end) were absorbed.
{
"success": true,
"data": {
"iceServers": [
{ "urls": "stun:…" },
{ "urls": "turn:…", "username": "…", "credential": "…" }
],
"turnConfigured": true
}
}turn.ring-platform.org A/AAAA → node LB IP).WEBRTC_STUN_URL, WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, WEBRTC_TURN_CREDENTIAL.Calls require a live Tunnel session. If realtime is disconnected, the UI refuses to start a call — fix Tunnel first (Tunnel Protocol).
features/messages/components/messages-shell.tsx| Wires hook + overlay |
infrastructure/k3s-or/stunner/ | GatewayClass, GatewayConfig, Gateway manifests |
k8s/ENV-PROD-WIRING.md | Prod env table for WEBRTC_* |
GET /api/webrtc/ice-servers — requires Auth.js session (401 if anonymous).
Response shape (verified):
STUN falls back to stun:stun.l.google.com:19302 when WEBRTC_STUN_URL is unset. TURN is added only when all of WEBRTC_TURN_URL, WEBRTC_TURN_USERNAME, and WEBRTC_TURN_CREDENTIAL are set.
| Variable | Where | Notes |
|---|---|---|
WEBRTC_STUN_URL | ConfigMap | Optional; Google STUN default in route |
WEBRTC_TURN_URL | ConfigMap | e.g. turn:turn.ring-platform.org:3478?transport=udp |
WEBRTC_TURN_USERNAME | Secret ring-platform-org-secrets | Matches STUNner auth Secret |
WEBRTC_TURN_CREDENTIAL | Secret | Never NEXT_PUBLIC_* |
Examples: k8s/secrets.example.yaml, wiring notes: k8s/ENV-PROD-WIRING.md.
env.local.template does not yet list these keys — use the k8s examples for local/prod parity.
Published on channel conversation:{conversationId} (same channel as typing):
| Event | Purpose |
|---|---|
call:invite | Outgoing ring |
call:accept / call:reject | Callee decision |
call:offer / call:answer | SDP |
call:ice | ICE candidates |
call:hangup | Tear down |
Subscribe with useTunnelChannel — do not raw-subscribe in effects (Tunnel Protocol).
Install operator (pulls Gateway API + STUNner CRDs):
Create auth Secret (type=static, username, password) and apply infrastructure/k3s-or/stunner/gateway.yaml (GatewayClass + GatewayConfig + Gateway with protocol TURN-UDP).
Wire app Secret/ConfigMap + ensure Deployment env refs for WEBRTC_TURN_USERNAME / WEBRTC_TURN_CREDENTIAL (k8s/deployment.yaml). Restart the app Deployment.
Smoke: external STUN Binding to :3478; authenticated GET /api/webrtc/ice-servers; two browsers on the same direct conversation.
Listener protocol must be TURN-UDP, not bare UDP. Realm in GatewayConfig is alphanumeric + hyphen (e.g. ring-platform-org). Empty UDPRoute backendRefs are invalid — peer TURN does not need a UDPRoute until an SFU (LiveKit) exists.
Connect Platform’s RTVS / FastTransponder stack is not ported — only control UX patterns (mute / camera / end) were absorbed.
{
"success": true,
"data": {
"iceServers": [
{ "urls": "stun:…" },
{ "urls": "turn:…", "username": "…", "credential": "…" }
],
"turnConfigured": true
}
}