Skip to main content

Voice and Video Calls

Voice and video calls use LiveKit for WebRTC. The backend exposes api/Call for tokens and call lifecycle; the frontend uses the LiveKit client and SignalR for call signaling (initiate, accept, reject, end).

Overview

  • Backend: api/Call — get LiveKit token, initiate call, accept, reject, end. Call initiation is also signaled via SignalR so the callee receives an incoming-call event.
  • LiveKit: Room-based; each call has a room name. Direct calls use a room like call_{callerId}_{receiverId}_{ticks}; group calls use groupcall_{groupId}_{ticks}.
  • Push: When the callee's tab or app is in the background, they can receive Web Push or Expo Push for incoming calls (see Web Push and Expo Push).

API Endpoints

MethodEndpointDescription
POST/api/Call/tokenGet LiveKit token for a room (body: roomName, optional displayName, canPublish, canSubscribe)
POST/api/Call/initiateInitiate a call (body: receiverId, optional callType e.g. "video", isGroupCall); returns roomName, token, url
POST/api/Call/acceptAccept an incoming call
POST/api/Call/rejectReject an incoming call
POST/api/Call/endEnd an active call

Flow

  1. Caller: Call POST /api/Call/initiate with receiverId (and optionally isGroupCall, callType). Backend creates a room name and returns a LiveKit token and URL.
  2. Signaling: Backend notifies the callee via SignalR (and optionally RabbitMQ for push). Callee sees incoming call UI.
  3. Callee: Accept → POST /api/Call/accept; then frontend gets a token (e.g. via same initiate flow or a dedicated token endpoint) and joins the LiveKit room.
  4. Both: Connect to LiveKit with the token and join the room for audio/video.
  5. End: Either party calls POST /api/Call/end; UI and room are cleaned up.

Configuration

  • LiveKit: Configure LiveKit:Url, LiveKit:ApiKey, LiveKit:ApiSecret in the backend (e.g. appsettings or environment). Default dev URL is ws://localhost:7880.
  • Frontend: LiveKit client and optional env (e.g. LiveKit URL) for the client SDK.