diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt index 26dc859a..a12e66bb 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt @@ -1098,6 +1098,9 @@ internal constructor( // Maximum amount of time it should ever take for an RPC request to reach the destination, and the ACK to come back // This is set to 7 seconds to account for various relay timeouts and retries in LiveKit Cloud that occur in rare cases val maxRoundTripLatency = 7.seconds + // Minimum allowed effective timeout to ensure the RPC lifecycle always has at least + // one second to complete, even after accounting for round-trip latency. + val minEffectiveTimeout = 1.seconds if (payload.byteLength() > RTCEngine.MAX_DATA_PACKET_SIZE) { throw RpcError.BuiltinRpcError.REQUEST_PAYLOAD_TOO_LARGE.create() @@ -1111,13 +1114,14 @@ internal constructor( } val requestId = UUID.randomUUID().toString() - + // Ensure the effective response timeout is not less than 1 second + val effectiveTimeout = (responseTimeout - maxRoundTripLatency).coerceAtLeast(minEffectiveTimeout) val result = publishRpcRequest( destinationIdentity = destinationIdentity, requestId = requestId, method = method, payload = payload, - responseTimeout = responseTimeout - maxRoundTripLatency, + responseTimeout = effectiveTimeout, ) if (result.isFailure) { diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/rpc/RpcManager.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/rpc/RpcManager.kt index 14e887c2..9bbf618d 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/rpc/RpcManager.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/rpc/RpcManager.kt @@ -79,6 +79,8 @@ interface RpcManager { * @param method The method name to call. * @param payload The payload to pass to the method. * @param responseTimeout Timeout for receiving a response after initial connection. + * If a value less than 8s is provided, it will be automatically clamped to 8s + * to ensure sufficient time for round-trip latency buffering. * Defaults to 15 seconds. * @return The response payload. * @throws RpcError on failure. Details in [RpcError.message].