ktor
ktor copied to clipboard
Fix websocket of browser received array buffer size is 0
Subsystem Server
Motivation websocket of browser received array buffer size is 0
Solution Use ByteBuffer.array() return ByteArray can work well
Hi @myfreax Can you please explain the problem and write test for your fix?
@rsinukov I try to find the reason, but I don't know why it is happening, the following code will not work correctly. But use ByteBuffer.array() return ByteArray can work well.
fun moveToByteArray(byteBuffer: ByteBuffer): ByteArray {
val array = ByteArray(byteBuffer.remaining())
byteBuffer.get(array)
return array
}
fun Application.configureSockets() {
var tcpReadChannel: ByteReadChannel? = null
var tcpWriteChannel: ByteWriteChannel? = null
install(WebSockets) {
pingPeriod = Duration.ofSeconds(15)
timeout = Duration.ofSeconds(15)
maxFrameSize = Long.MAX_VALUE
masking = false
}
CoroutineScope(Dispatchers.IO).launch {
val socket = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect("127.0.0.1", port = 9002){
this.noDelay = false
}
tcpReadChannel = socket.openReadChannel()
tcpWriteChannel = socket.openWriteChannel(autoFlush = true)
}
routing {
webSocket("/") {
launch(Dispatchers.IO) {
while (true) {
val byteBuffer = ByteBuffer.allocate(tcpReadChannel?.availableForRead!!)
val len = tcpReadChannel?.readFully(byteBuffer)
if (len != 0) {
launch {
val byteArray = moveToByteArray(byteBuffer)
outgoing.send(Frame.Binary(true, byteArray)) //byteArray.size is 0
//println("TCP Client Send Data To Websocket Server: ${StandardCharsets.UTF_8.decode(byteBuffer)}") //print empty string""
}
}
}
}
for (frame in incoming) {
tcpWriteChannel?.writeFully(appendCRLF(frame.buffer))
///println("WebSocket Server Received Data From Browser Client: ${StandardCharsets.UTF_8.decode(frame.buffer)}")
}
}
}
}
Trying the following test code also works fine, but in the above scenario it works. For unknown reasons, I'm having a hard time writing tests for the above scenarios.
val byteBuffer = ByteBuffer.wrap("aa".toByteArray())
val array = ByteArray(byteBuffer.remaining())
byteBuffer.get(array)
println(array.size)
I'm closing this PR because we can't accept this change. array() function will return the backing array of ByteBuffer which will have all the future changes in the ByteBuffer.