Fix PlatformSocket on Android

This commit is contained in:
Him188 2020-01-29 20:12:47 +08:00
parent a79032e8cd
commit 5ae4296bd5
2 changed files with 25 additions and 9 deletions

View File

@ -1,10 +1,14 @@
package net.mamoe.mirai.utils.io package net.mamoe.mirai.utils.io
import io.ktor.network.selector.ActorSelectorManager
import io.ktor.network.sockets.Socket import io.ktor.network.sockets.Socket
import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.aSocket
import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openReadChannel
import io.ktor.network.sockets.openWriteChannel import io.ktor.network.sockets.openWriteChannel
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.coroutines.io.ByteWriteChannel
import kotlinx.coroutines.io.readAvailable import kotlinx.coroutines.io.readAvailable
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
@ -17,24 +21,28 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
@MiraiInternalAPI @MiraiInternalAPI
actual class PlatformSocket : Closeable { actual class PlatformSocket : Closeable {
@UseExperimental(KtorExperimentalAPI::class) @UseExperimental(KtorExperimentalAPI::class)
lateinit var channel: Socket lateinit var socket: Socket
@UseExperimental(KtorExperimentalAPI::class) @UseExperimental(KtorExperimentalAPI::class)
actual val isOpen: Boolean actual val isOpen: Boolean
get() = channel.socketContext.isActive get() = socket.socketContext.isActive
override fun close() = channel.dispose() override fun close() = socket.dispose()
@PublishedApi @PublishedApi
internal val writeChannel = channel.openWriteChannel(true) internal lateinit var writeChannel: ByteWriteChannel
@PublishedApi @PublishedApi
internal val readChannel = channel.openReadChannel() internal lateinit var readChannel: ByteReadChannel
/** /**
* @throws SendPacketInternalException * @throws SendPacketInternalException
*/ */
actual suspend inline fun send(packet: ByteReadPacket) { actual suspend inline fun send(packet: ByteReadPacket) {
try {
writeChannel.writePacket(packet) writeChannel.writePacket(packet)
} catch (e: Exception) {
throw SendPacketInternalException(e)
}
} }
/** /**
@ -43,13 +51,19 @@ actual class PlatformSocket : Closeable {
actual suspend inline fun read(): ByteReadPacket { actual suspend inline fun read(): ByteReadPacket {
// do not use readChannel.readRemaining() !!! this function never returns // do not use readChannel.readRemaining() !!! this function never returns
ByteArrayPool.useInstance { buffer -> ByteArrayPool.useInstance { buffer ->
val count = readChannel.readAvailable(buffer) val count = try {
readChannel.readAvailable(buffer)
} catch (e: Exception) {
throw ReadPacketInternalException(e)
}
return buffer.toReadPacket(0, count) return buffer.toReadPacket(0, count)
} }
} }
@UseExperimental(KtorExperimentalAPI::class) @UseExperimental(KtorExperimentalAPI::class)
actual suspend fun connect(serverHost: String, serverPort: Int) { actual suspend fun connect(serverHost: String, serverPort: Int) {
channel = aSocket(io.ktor.network.selector.ActorSelectorManager(kotlinx.coroutines.Dispatchers.IO)).tcp().connect(serverHost, serverPort) socket = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect(serverHost, serverPort)
writeChannel = socket.openWriteChannel(true)
readChannel = socket.openReadChannel()
} }
} }

View File

@ -1,10 +1,12 @@
package net.mamoe.mirai.utils.io package net.mamoe.mirai.utils.io
import io.ktor.network.selector.ActorSelectorManager
import io.ktor.network.sockets.Socket import io.ktor.network.sockets.Socket
import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.aSocket
import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openReadChannel
import io.ktor.network.sockets.openWriteChannel import io.ktor.network.sockets.openWriteChannel
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.io.ByteReadChannel import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.coroutines.io.ByteWriteChannel import kotlinx.coroutines.io.ByteWriteChannel
import kotlinx.coroutines.io.readAvailable import kotlinx.coroutines.io.readAvailable
@ -60,7 +62,7 @@ actual class PlatformSocket : Closeable {
@UseExperimental(KtorExperimentalAPI::class) @UseExperimental(KtorExperimentalAPI::class)
actual suspend fun connect(serverHost: String, serverPort: Int) { actual suspend fun connect(serverHost: String, serverPort: Int) {
socket = aSocket(io.ktor.network.selector.ActorSelectorManager(kotlinx.coroutines.Dispatchers.IO)).tcp().connect(serverHost, serverPort) socket = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect(serverHost, serverPort)
writeChannel = socket.openWriteChannel(true) writeChannel = socket.openWriteChannel(true)
readChannel = socket.openReadChannel() readChannel = socket.openReadChannel()
} }