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.withContext
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer
import kotlinx.io.nio.read
import kotlinx.io.nio.readPacketAtMost
import kotlinx.io.nio.writePacket
import java.net.InetSocketAddress
import java.nio.channels.DatagramChannel
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)
actual typealias ClosedChannelException = java.nio.channels.ClosedChannelException
@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 {
(channel as ReadableByteChannel).read(buffer)
} catch (e: Throwable) {
throw ReadPacketInternalException(e)
}
}
@Throws(SendPacketInternalException::class)
actual suspend fun send(buffer: IoBuffer) = withContext(Dispatchers.IO) {
buffer.readDirect {
try {
channel.send(it, serverAddress)
(channel as WritableByteChannel).writePacket(packet)
} catch (e: Throwable) {
throw SendPacketInternalException(e)
}
}
}
override fun close() {
channel.close()
actual suspend inline fun read(): ByteReadPacket = withContext(Dispatchers.IO) {
try {
(channel as ReadableByteChannel).readPacketAtMost(Long.MAX_VALUE)
} catch (e: Throwable) {
throw ReadPacketInternalException(e)
}
}
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
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer
import kotlinx.io.errors.IOException
import net.mamoe.mirai.utils.MiraiInternalAPI
/**
* 多平台适配的 DatagramChannel.
*/
@MiraiInternalAPI
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
}

View File

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