Frequent data transmission can lead to connection interruption
Sending audio and video frames using Quic will interrupt the transmission of data, and the data packet has been modified based on feedback from the server
`package com.saida.video_call.quic.library.quic
import android.util.Log import com.saida.play.video_play_plugin.quic.Message import com.saida.play.video_play_plugin.quic.utils.IO import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import tech.kwik.agent15.env.PlatformMapping import tech.kwik.core.ConnectionEstablishedEvent import tech.kwik.core.ConnectionListener import tech.kwik.core.ConnectionTerminatedEvent import tech.kwik.core.QuicClientConnection import tech.kwik.core.QuicStream import tech.kwik.core.log.SysOutLogger import java.io.BufferedInputStream import java.io.BufferedOutputStream import java.io.OutputStream import java.net.URI import java.util.concurrent.locks.ReentrantLock import kotlinx.coroutines.channels.Channel import kotlin.coroutines.cancellation.CancellationException
class QUICConnection(var quicStreamInterface: QUICStreamInterface) : ConnectionListener {
companion object {
private const val TAG = "QUICConnection"
private var mQUICConnection: QuicClientConnection? = null
private var mQUICStream: QuicStream? = null
private var mQUICOutputStream: OutputStream? = null
private var mQUICInputStream: BufferedInputStream? = null
}
private var handshakeData: ByteArray? = null
private var mLock = ReentrantLock()
fun initQUICConnection(ip: String, handshakeData1: ByteArray) {
val connectionListener = this
CoroutineScope(Dispatchers.IO).launch {
PlatformMapping.usePlatformMapping(PlatformMapping.Platform.Android)
var log = SysOutLogger()
log.logDebug(true)
log.logRaw(true)
log.logDecrypted(true)
log.logSecrets(true)
log.logPackets(true)
log.logInfo(true)
log.logWarning(true)
log.logStats(true)
log.logRecovery(true)
log.logCongestionControl(true)
log.logFlowControl(true)
log.useRelativeTime(true)
try {
mQUICConnection = QuicClientConnection.newBuilder()
.noServerCertificateCheck()
.uri(URI.create(String.format("SaidaClient://%s", ip)))
.defaultStreamReceiveBufferSize((1024 * 1024 * 2))
.applicationProtocol("SaidaClient")
.enableDatagramExtension()
.logger(log)
.build()
handshakeData = handshakeData1
mQUICConnection?.setConnectionListener(connectionListener)
mQUICConnection?.connect()
} catch (e: Exception) {
Log.d(TAG, "initQUICConnection: " + e.message)
quicStreamInterface.disconnected()
}
}
}
fun sendData(data: ByteArray) {
CoroutineScope(Dispatchers.IO).launch {
mLock.lock()
try {
if (mQUICOutputStream == null) {
return@launch
}
mQUICOutputStream?.write(data)
mQUICOutputStream?.flush()
} catch (e: Exception) {
} finally {
mLock.unlock()
}
}
}
fun release() {
mQUICOutputStream?.close()
mQUICInputStream?.close()
mQUICConnection?.closeAndWait()
mQUICOutputStream = null
mQUICConnection = null
mQUICInputStream = null
}
override fun disconnected(connectionTerminatedEvent: ConnectionTerminatedEvent?) {
quicStreamInterface.disconnected()
release()
}
override fun connected(connectionEstablishedEvent: ConnectionEstablishedEvent?) {
super.connected(connectionEstablishedEvent)
mQUICStream = mQUICConnection?.createStream(true)
mQUICInputStream =
BufferedInputStream(mQUICStream!!.inputStream, 1024 * 1024 * 2)
mQUICOutputStream = mQUICStream?.outputStream
sendData(handshakeData!!)
val header = ByteArray(12)
quicStreamInterface.connected()
CoroutineScope(Dispatchers.IO).launch {
try {
while (true) {
IO.readFull(mQUICInputStream, header, 0, 12)
val headerObj = Message.Header.newHeader(header)
when (headerObj.subType) {
Message.Header.MEDIA_CONTROL_TYPE_KEY_FRAME -> {
quicStreamInterface.requestStreamKeyFrame()
}
}
}
} catch (e: Exception) {
e.message
}
}
}
}`
log:
Can you explain what you mean by
- Quic will interrupt the transmission of data
- the data packet has been modified
Try to make it very concrete. What do see, what is happening that you didn't expect? How did you notice? Do you have some "evidence", e.g. a WireShark capture that shows what is going on? Why do you think the problem is in Kwik?
I would really like to investigate, but I need more information; now I don't need were to start.
Cheers Peter
I notice you enable the datagram extension. Do you really use it? Datagram extension is sending data unreliably by design!
quic-log.zip I deleted the datagram but still encountered this issue. Currently, I obtained the data through WireShark
To make sense of the pcap, i also need the keys. You can let kwik export the keys.
And you still need to explain what exactly your problem is, as i asked in the previous comment. I don't have a crystal ball, for me to investigate an issue, I do need to know what exactly the issue is.
Hi @jiajialaixi
Any update? If you found/fixed the issue yourself, please let me know so we can close this issue.
I haven't found where the problem lies yet. Currently, there is a packet sticking issue with the data I transmit using TCP. If I replace the corresponding transmission function with KWIK, this problem will also occur. However, using TCP's middle function setTcpNoDelay can solve the corresponding packet sticking issue. KWIK has not found any API to handle this function yet
Simulate sending 320 bytes of audio in 40 milliseconds and 5000 bytes of video data in 25 milliseconds to reproduce
I don't understand what you mean by "packet sticking". There is no delay in current version of Kwik, when you write one byte, it is sent immediately.
How are these 320 bytes sent? One block of 320 bytes, or 10 times 32 bytes, how big was the delay in between, etc. What is going wrong exactly? What do you see what is happening or is not happening? If bytes are not received, which bytes? Just the last part, or bytes somewhere in the middle of the data? Don't say: bytes are not sent, if you are not sure this is the case, maybe there is a bug in your receiver that makes it look these bytes are not received. By precise about what you see.
Please configure kwik to write the secrets to a file, record a session with WireShark and provide me with the pcap and the secrets. This will give facts that might help to track down the issue.
You need to be much more specific and precise. Kwik sends files of all kinds of sizes and in with all kinds of network conditions without any error, this is tested 3x a day with the interop tests (https://interop.seemann.io), so if you experience data loss, there is something very special about your case, which we need to find. I cannot find a problem when I do not understand what the problem exactly is. Talking "sticking packets" does not help, I need facts. E.g. "I sent 320 bytes of data and I received only 269 and when I compare data sent and data received it seems that 41 consecutive bytes in the middle of these 320 byte are missing. It can't be a bug in my server because ....... The WireShark capture shows that for stream 4, the bytes at position 120 - 160 in the stream are never sent". Ok?
Any news @jiajialaixi ?
The same connection works fine on Java, but there is a current issue on Android that has not been identified yet