Rewrite PlatformDatagramChannel, easier to use

This commit is contained in:
Him188 2020-01-06 18:29:52 +08:00
parent f5261b257e
commit 9bc3d933f7
3 changed files with 66 additions and 61 deletions

View File

@ -2,43 +2,42 @@ package net.mamoe.mirai.utils.io
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer import kotlinx.io.nio.readPacketAtMost
import kotlinx.io.nio.read import kotlinx.io.nio.writePacket
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.nio.channels.DatagramChannel import java.nio.channels.DatagramChannel
import java.nio.channels.ReadableByteChannel import java.nio.channels.ReadableByteChannel
import java.nio.channels.WritableByteChannel
actual class PlatformDatagramChannel actual constructor(serverHost: String, serverPort: Short) : Closeable { actual typealias ClosedChannelException = java.nio.channels.ClosedChannelException
private val serverAddress: InetSocketAddress = InetSocketAddress(serverHost, serverPort.toInt())
private val channel: DatagramChannel = DatagramChannel.open().connect(serverAddress)
@Throws(ReadPacketInternalException::class) /**
actual suspend fun read(buffer: IoBuffer) = withContext(Dispatchers.IO) { * 多平台适配的 DatagramChannel.
*/
actual class PlatformDatagramChannel actual constructor(
serverHost: String,
serverPort: Short
) : Closeable {
@PublishedApi
internal val channel: DatagramChannel = DatagramChannel.open().connect(InetSocketAddress(serverHost, serverPort.toInt()))
actual val isOpen: Boolean get() = channel.isOpen
override fun close() = channel.close()
actual suspend inline fun send(packet: ByteReadPacket): Boolean = withContext(Dispatchers.IO) {
try { try {
(channel as WritableByteChannel).writePacket(packet)
} catch (e: Throwable) {
throw SendPacketInternalException(e)
}
}
(channel as ReadableByteChannel).read(buffer) actual suspend inline fun read(): ByteReadPacket = withContext(Dispatchers.IO) {
try {
(channel as ReadableByteChannel).readPacketAtMost(Long.MAX_VALUE)
} catch (e: Throwable) { } catch (e: Throwable) {
throw ReadPacketInternalException(e) throw ReadPacketInternalException(e)
} }
} }
}
@Throws(SendPacketInternalException::class)
actual suspend fun send(buffer: IoBuffer) = withContext(Dispatchers.IO) {
buffer.readDirect {
try {
channel.send(it, serverAddress)
} catch (e: Throwable) {
throw SendPacketInternalException(e)
}
}
}
override fun close() {
channel.close()
}
actual val isOpen: Boolean get() = channel.isOpen
}
actual typealias ClosedChannelException = java.nio.channels.ClosedChannelException

View File

@ -1,16 +1,24 @@
package net.mamoe.mirai.utils.io package net.mamoe.mirai.utils.io
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer
import kotlinx.io.errors.IOException import kotlinx.io.errors.IOException
import net.mamoe.mirai.utils.MiraiInternalAPI
/** /**
* 多平台适配的 DatagramChannel. * 多平台适配的 DatagramChannel.
*/ */
@MiraiInternalAPI
expect class PlatformDatagramChannel(serverHost: String, serverPort: Short) : Closeable { expect class PlatformDatagramChannel(serverHost: String, serverPort: Short) : Closeable {
/**
* @throws SendPacketInternalException
*/
suspend inline fun send(packet: ByteReadPacket): Boolean
suspend fun read(buffer: IoBuffer): Int /**
suspend fun send(buffer: IoBuffer): Int * @throws ReadPacketInternalException
*/
suspend inline fun read(): ByteReadPacket
val isOpen: Boolean val isOpen: Boolean
} }

View File

@ -2,49 +2,47 @@ package net.mamoe.mirai.utils.io
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer import kotlinx.io.nio.readPacketAtMost
import kotlinx.io.nio.read import kotlinx.io.nio.writePacket
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.nio.channels.DatagramChannel import java.nio.channels.DatagramChannel
import java.nio.channels.ReadableByteChannel import java.nio.channels.ReadableByteChannel
import java.nio.channels.WritableByteChannel
actual class PlatformDatagramChannel actual constructor(serverHost: String, serverPort: Short) : Closeable {
private val serverAddress: InetSocketAddress = InetSocketAddress(serverHost, serverPort.toInt())
private val channel: DatagramChannel = DatagramChannel.open().connect(serverAddress)
@Throws(ReadPacketInternalException::class) actual typealias ClosedChannelException = java.nio.channels.ClosedChannelException
actual suspend fun read(buffer: IoBuffer) = withContext(Dispatchers.IO) {
/**
* 多平台适配的 DatagramChannel.
*/
actual class PlatformDatagramChannel actual constructor(
serverHost: String,
serverPort: Short
) : Closeable {
@PublishedApi
internal val channel: DatagramChannel = DatagramChannel.open().connect(InetSocketAddress(serverHost, serverPort.toInt()))
actual val isOpen: Boolean get() = channel.isOpen
override fun close() = channel.close()
actual suspend inline fun send(packet: ByteReadPacket): Boolean = withContext(Dispatchers.IO) {
try { try {
(channel as ReadableByteChannel).read(buffer) (channel as WritableByteChannel).writePacket(packet)
} catch (e: ClosedChannelException) { } catch (e: Throwable) {
throw e throw SendPacketInternalException(e)
}
}
actual suspend inline fun read(): ByteReadPacket = withContext(Dispatchers.IO) {
try {
(channel as ReadableByteChannel).readPacketAtMost(Long.MAX_VALUE)
} catch (e: Throwable) { } catch (e: Throwable) {
throw ReadPacketInternalException(e) throw ReadPacketInternalException(e)
} }
} }
@Throws(SendPacketInternalException::class)
actual suspend fun send(buffer: IoBuffer) = withContext(Dispatchers.IO) {
buffer.readDirect {
try {
channel.send(it, serverAddress)
} catch (e: Throwable) {
throw SendPacketInternalException(e)
}
}
}
override fun close() {
channel.close()
}
actual val isOpen: Boolean get() = channel.isOpen
} }
actual typealias ClosedChannelException = java.nio.channels.ClosedChannelException
/* /*
actual class PlatformDatagramChannel actual constructor(serverHost: String, serverPort: Short) : Closeable { actual class PlatformDatagramChannel actual constructor(serverHost: String, serverPort: Short) : Closeable {