WebRTC client
Web Real-Time Communication (WebRTC) is a set of standards and APIs for real-time, peer-to-peer communication in browsers and native apps.
The WebRTC client in Ktor enables real-time peer-to-peer communication in multiplatform projects. With WebRTC, you can build features such as:
Video and voice calls
Multiplayer games
Collaborative applications, such as whiteboards and editors
Low-latency data exchange between clients
Add dependencies
To use WebRtcClient, you need to include the ktor-client-webrtc artifact in the build script:
Create a client
When creating a WebRtcClient, choose an engine based on your target platform:
JS/Wasm:
JsWebRtcuses the browser WebRTC and Media Capture and Streams APIs.Android:
AndroidWebRtcuses the precompiled Stream WebRTC library for Android and Android media APIs.iOS:
IosWebRtcuses the WebRTC SDK and the native AVFoundation framework.JVM:
JvmWebRtcuses native WebRTC bindings provided by webrtc-java.
You can then provide platform-specific configuration similar to HttpClient. STUN/TURN servers are required for ICE to work correctly. You can use existing solutions such as coturn:
Create a connection and negotiate SDP
After creating a WebRtcClient, the next step is to create a peer connection. A peer connection is the core object that manages the real-time communication between two clients.
To establish a connection, WebRTC uses the Session Description Protocol (SDP). This involves three steps:
One peer (the caller) creates an offer.
The other peer (the callee) responds with an answer.
Both peers apply each other’s descriptions to complete the setup.
Exchange ICE candidates
Once SDP negotiation is complete, peers still need to discover how to connect across networks. Interactive Connectivity Establishment (ICE) allows peers to find network paths to each other.
Each peer gathers its own ICE candidates.
These candidates must be sent to the other peer through your chosen signaling channel.
Once both peers add each other’s candidates, the connection can succeed.
Use a data channel
WebRTC supports data channels, which let peers exchange arbitrary messages. This is useful for chat, multiplayer games, collaborative tools, or any low-latency messaging between clients.
Creating a channel
To create a channel on one side, use the .createDataChannel() method:
You can then listen for data channel events on the other side:
DataChannelEvent can represent the following events:
Open: The channel is ready to send and receive data.Closing: The channel has started closing.Closed: The channel is closed.BufferedAmountLow: The amount of buffered outgoing data has dropped to or belowbufferedAmountLowThreshold.Error: An error occurred on the channel. This event is not emitted on JVM. Send failures throwWebRtc.IOExceptioninstead.
To receive BufferedAmountLow set a threshold on the channel:
Sending and receiving messages
Channels use a Channel-like API, familiar to Kotlin developers:
Add and observe media tracks
In addition to data channels, WebRTC supports media tracks for audio and video. This allows you to build applications such as video calls or screen sharing.
Creating local tracks
You can request audio or video tracks from local devices (microphone, camera):
Media capture is platform-specific:
On the web, it uses
navigator.mediaDevices.getUserMedia.On Android, it uses the Camera2 API. You need to request camera and microphone permissions separately.
On iOS, it uses the AVFoundation API. You also need to request the required permissions separately.
On JVM, it uses webrtc-java to access the system camera and microphone. The operating system may prompt the user for permission.
The client selects the most suitable media device based on the specified constraints. If no suitable device is available, it throws WebRtcMedia.DeviceException.
Receiving remote tracks
You can also listen for remote media tracks:
Platform-specific logic
This API provides high-level abstractions, but there are use-cases that may require accessing platform-specific APIs. You can use the .getNative() extension functions to retrieve the underlying implementations. Platform-specific libraries are exposed as transitive libraries, except for WebRTC-SDK CocoaPod on iOS.
To use the WebRTC-SDK API, you need to install it manually:
Limitations
The WebRTC client is experimental and has the following limitations:
Signaling: Signaling is not included. You need to implement it separately, for example, with WebSockets or HTTP.
Platform support: The client supports JavaScript/Wasm, Android, iOS, and JVM desktop. Kotlin/Native support is planned for a future release.
Permissions: Permissions must be handled by your application. Browsers prompt users for microphone and camera access. Android and iOS require runtime permission requests. On JVM, camera and microphone access are granted at the operating-system level.
JVM limitations: Candidate prefetching is not supported.
iceCandidatePoolSizemust be0or omitted. ThefacingMode,aspectRatio, andresizeModevideo constraints are not supported and throw an exception if set.DataChannelEvent.Erroris not emitted.Media features: Only basic audio and video tracks are supported. Screen sharing, device selection, simulcast, and advanced RTP features are not yet available.
Connection statistics: Statistics are available but differ across platforms and do not follow a unified schema.