Skip to content

Use Java socket by default for RTMP#2100

Open
mkrn wants to merge 2 commits into
pedroSG94:masterfrom
mkrn:fix/rtmp-default-java-socket
Open

Use Java socket by default for RTMP#2100
mkrn wants to merge 2 commits into
pedroSG94:masterfrom
mkrn:fix/rtmp-default-java-socket

Conversation

@mkrn
Copy link
Copy Markdown
Contributor

@mkrn mkrn commented Jun 3, 2026

Summary

Change the default RTMP socket implementation from Ktor to Java sockets. Ktor remains available via setSocketType(SocketType.KTOR), but new RtmpClient instances default to SocketType.JAVA.

Why

The Ktor RTMPS path can crash the app when the network is interrupted or the remote peer closes the connection while TLS is shutting down. We reproduced this in a production app by streaming to an rtmps:// endpoint, disabling Wi-Fi during the stream, and watching the process crash from Ktor's internal TLS closer coroutine.

Observed crash shape:

io.ktor.utils.io.ClosedWriteChannelException: Broken pipe
  at io.ktor.utils.io.ByteChannel.getWriteBuffer(ByteChannel.kt:54)
  at io.ktor.utils.io.ByteWriteChannelOperationsKt.writeByte(ByteWriteChannelOperations.kt:19)
  at io.ktor.network.tls.RenderKt.writeRecord(Render.kt:18)
  at io.ktor.network.tls.TLSClientHandshake...
Suppressed: [CoroutineName(cio-tls-closer), ... Dispatchers.IO]
Caused by: java.io.IOException: Broken pipe
  at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:512)
  at io.ktor.network.sockets.CIOWriterKt...

This is consistent with #1856 and #2085. In #1856, Java sockets were suggested as the workaround and as a possible safer default. In our device test, switching RTMP to SocketType.JAVA stopped the fatal process crash while preserving reconnect behavior.

Verification

  • ./gradlew :rtmp:assemble
  • Android device test against an rtmps:// endpoint:
    • baseline stream packets: pass
    • zoom controls: pass
    • background/foreground: pass
    • Wi-Fi off/on during stream: pass, no fatal crash
    • Wi-Fi/mobile/Wi-Fi transition: pass, no fatal crash

Compatibility

This preserves the public API and keeps Ktor opt-in through setSocketType(SocketType.KTOR). The change only affects the default for RTMP clients.

Related: #1856, #2085

@pedroSG94
Copy link
Copy Markdown
Owner

Hello,

Thank you for the reports. I added 2 comments to the PR.
I'm fine with the idea to switch to java socket by default and I will do it but we should check the review comments to avoid problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants