mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 04:50:26 +08:00
Multiplatform HttpClient and fix time formatting
This commit is contained in:
parent
4fe56409ec
commit
7a3576fe3e
mirai-core-utils
mirai-core
build.gradle.kts
src
commonMain/kotlin
commonTest/kotlin/event
darwinMain/kotlin
darwinTest/kotlin
jvmBaseMain/kotlin
linuxX64Main/kotlin
linuxX64Test/kotlin
mingwX64Main/kotlin
nativeTest/kotlin/network/framework
@ -76,7 +76,7 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
val mingwMain by getting {
|
||||
val mingwX64Main by getting {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,13 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.atomicfu.locks.ReentrantLock
|
||||
import kotlinx.atomicfu.locks.withLock
|
||||
import kotlinx.cinterop.*
|
||||
import platform.posix.*
|
||||
import platform.posix.localtime
|
||||
import platform.posix.strftime
|
||||
import platform.posix.time
|
||||
import platform.posix.time_tVar
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
@ -27,18 +32,22 @@ public actual fun currentTimeMillis(): Long {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val timeLock = ReentrantLock()
|
||||
|
||||
@OptIn(UnsafeNumber::class)
|
||||
public actual fun currentTimeFormatted(format: String?): String {
|
||||
public actual fun currentTimeFormatted(format: String?): String = timeLock.withLock {
|
||||
memScoped {
|
||||
val timeT = alloc<time_tVar>()
|
||||
time(timeT.ptr)
|
||||
val tm = localtime(timeT.ptr)
|
||||
try {
|
||||
val bb = allocArray<ByteVar>(40)
|
||||
strftime(bb, 40, "%Y-%M-%d %H:%M:%S", tm);
|
||||
return bb.toKString()
|
||||
} finally {
|
||||
free(tm)
|
||||
}
|
||||
|
||||
// http://www.cplusplus.com/reference/clibrary/ctime/localtime/
|
||||
// tm returns a static pointer which doesn't need to free
|
||||
val tm = localtime(timeT.ptr) // localtime is not thread-safe
|
||||
|
||||
val bb = allocArray<ByteVar>(40)
|
||||
strftime(bb, 40, "%Y-%M-%d %H:%M:%S", tm);
|
||||
|
||||
bb.toKString()
|
||||
}
|
||||
}
|
@ -57,6 +57,8 @@ kotlin {
|
||||
implementation(bouncycastle)
|
||||
implementation(`log4j-api`)
|
||||
implementation(`netty-all`)
|
||||
implementation(`ktor-client-okhttp`)
|
||||
api(`kotlinx-coroutines-core`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,23 +105,25 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
val mingwMain by getting {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
configure((LINUX_TARGETS + WIN_TARGETS).map { getByName(it + "Main") }) {
|
||||
configure(WIN_TARGETS.map { getByName(it + "Main") }) {
|
||||
dependencies {
|
||||
implementation(`ktor-client-curl`)
|
||||
}
|
||||
}
|
||||
|
||||
configure(MAC_TARGETS.map { getByName(it + "Main") }) {
|
||||
configure(LINUX_TARGETS.map { getByName(it + "Main") }) {
|
||||
dependencies {
|
||||
implementation(`ktor-client-curl`)
|
||||
}
|
||||
}
|
||||
|
||||
val darwinMain by getting {
|
||||
dependencies {
|
||||
implementation(`ktor-client-ios`)
|
||||
}
|
||||
}
|
||||
|
||||
disableCrossCompile()
|
||||
// val unixMain by getting {
|
||||
// dependencies {
|
||||
// implementation(`ktor-client-cio`)
|
||||
|
@ -12,6 +12,7 @@
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.*
|
||||
import io.ktor.client.features.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.request.forms.*
|
||||
@ -72,6 +73,8 @@ import kotlin.jvm.JvmName
|
||||
|
||||
internal fun getMiraiImpl() = Mirai as MiraiImpl
|
||||
|
||||
internal expect fun createDefaultHttpClient(): HttpClient
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal expect fun _MiraiImpl_static_init()
|
||||
|
||||
@ -152,13 +155,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
|
||||
override var FileCacheStrategy: FileCacheStrategy = net.mamoe.mirai.utils.FileCacheStrategy.PlatformDefault
|
||||
|
||||
@Deprecated("Mirai is not going to use ktor. This is deprecated for removal.", level = DeprecationLevel.WARNING)
|
||||
override var Http: HttpClient = HttpClient() {
|
||||
install(HttpTimeout) {
|
||||
this.requestTimeoutMillis = 30_0000
|
||||
this.connectTimeoutMillis = 30_0000
|
||||
this.socketTimeoutMillis = 30_0000
|
||||
}
|
||||
}
|
||||
override var Http: HttpClient = createDefaultHttpClient()
|
||||
|
||||
override suspend fun acceptNewFriendRequest(event: NewFriendRequestEvent) {
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
|
@ -12,14 +12,12 @@ package net.mamoe.mirai.internal.event
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.first
|
||||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
|
||||
import net.mamoe.mirai.event.GlobalEventChannel
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.internal.test.runBlockingUnit
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertIs
|
||||
|
||||
@JvmBlockingBridge
|
||||
internal class EventChannelFlowTest : AbstractEventTest() {
|
||||
|
||||
@Test
|
||||
|
@ -21,7 +21,6 @@ import net.mamoe.mirai.event.events.MessageEvent
|
||||
import kotlin.coroutines.coroutineContext
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.test.*
|
||||
|
||||
internal class EventChannelTest : AbstractEventTest() {
|
||||
@ -37,7 +36,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
@Test
|
||||
fun singleFilter() {
|
||||
runBlocking {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.filterIsInstance<TE>()
|
||||
.filter {
|
||||
@ -69,7 +68,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
@Test
|
||||
fun multipleFilters() {
|
||||
runBlocking {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.filterIsInstance<TE>()
|
||||
.filter {
|
||||
@ -109,7 +108,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun multipleContexts1() {
|
||||
runBlocking {
|
||||
withContext(CoroutineName("1")) {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.context(CoroutineName("2"))
|
||||
.context(CoroutineName("3"))
|
||||
@ -132,7 +131,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun multipleContexts2() {
|
||||
runBlocking {
|
||||
withContext(CoroutineName("1")) {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.context(CoroutineName("2"))
|
||||
.context(CoroutineName("3"))
|
||||
@ -156,7 +155,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun multipleContexts3() {
|
||||
runBlocking {
|
||||
withContext(CoroutineName("1")) {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.context(CoroutineName("2"))
|
||||
.subscribeOnce<TE> {
|
||||
@ -178,7 +177,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun multipleContexts4() {
|
||||
runBlocking {
|
||||
withContext(CoroutineName("1")) {
|
||||
val received = suspendCoroutine<Int> { cont ->
|
||||
val received = suspendCancellableCoroutine { cont ->
|
||||
globalEventChannel()
|
||||
.subscribeOnce<TE> {
|
||||
assertEquals("1", currentCoroutineContext()[CoroutineName]!!.name)
|
||||
@ -250,7 +249,8 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun testExceptionInFilter() {
|
||||
assertFailsWith<ExceptionInEventChannelFilterException> {
|
||||
runBlocking {
|
||||
suspendCoroutine<Int> { cont ->
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
suspendCancellableCoroutine<Int> { cont ->
|
||||
globalEventChannel()
|
||||
.exceptionHandler {
|
||||
cont.resumeWithException(it)
|
||||
@ -278,7 +278,7 @@ internal class EventChannelTest : AbstractEventTest() {
|
||||
fun testExceptionInSubscribe() {
|
||||
runBlocking {
|
||||
assertFailsWith<IllegalStateException> {
|
||||
suspendCoroutine<Int> { cont ->
|
||||
suspendCancellableCoroutine<Int> { cont ->
|
||||
val handler = CoroutineExceptionHandler { _, throwable ->
|
||||
cont.resumeWithException(throwable)
|
||||
}
|
||||
|
@ -60,10 +60,11 @@ internal class EventTests : AbstractEventTest() {
|
||||
resetEventListeners()
|
||||
var listeners = 0
|
||||
val counter = atomic(0)
|
||||
val channel = scope.globalEventChannel()
|
||||
for (p in EventPriority.values()) {
|
||||
repeat(2333) {
|
||||
listeners++
|
||||
scope.globalEventChannel().subscribeAlways<ParentEvent> {
|
||||
channel.subscribeAlways<ParentEvent> {
|
||||
counter.getAndIncrement()
|
||||
}
|
||||
}
|
||||
|
24
mirai-core/src/darwinMain/kotlin/MiraiImpl.kt
Normal file
24
mirai-core/src/darwinMain/kotlin/MiraiImpl.kt
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.ios.*
|
||||
import io.ktor.client.features.*
|
||||
|
||||
internal actual fun createDefaultHttpClient(): HttpClient {
|
||||
return HttpClient(Ios) {
|
||||
install(HttpTimeout) {
|
||||
this.requestTimeoutMillis = 30_0000
|
||||
this.connectTimeoutMillis = 30_0000
|
||||
this.socketTimeoutMillis = 30_0000
|
||||
}
|
||||
}
|
||||
}
|
10
mirai-core/src/darwinTest/kotlin/package.kt
Normal file
10
mirai-core/src/darwinTest/kotlin/package.kt
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
@ -11,7 +11,23 @@
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import io.ktor.client.features.*
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal actual fun _MiraiImpl_static_init() {
|
||||
// nop
|
||||
}
|
||||
|
||||
internal actual fun createDefaultHttpClient(): HttpClient {
|
||||
return HttpClient(OkHttp) {
|
||||
install(HttpTimeout) {
|
||||
this.requestTimeoutMillis = 30_0000
|
||||
this.connectTimeoutMillis = 30_0000
|
||||
this.socketTimeoutMillis = 30_0000
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
24
mirai-core/src/linuxX64Main/kotlin/MiraiImpl.kt
Normal file
24
mirai-core/src/linuxX64Main/kotlin/MiraiImpl.kt
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.curl.*
|
||||
import io.ktor.client.features.*
|
||||
|
||||
internal actual fun createDefaultHttpClient(): HttpClient {
|
||||
return HttpClient(Curl) {
|
||||
install(HttpTimeout) {
|
||||
this.requestTimeoutMillis = 30_0000
|
||||
this.connectTimeoutMillis = 30_0000
|
||||
this.socketTimeoutMillis = 30_0000
|
||||
}
|
||||
}
|
||||
}
|
10
mirai-core/src/linuxX64Main/kotlin/package.kt
Normal file
10
mirai-core/src/linuxX64Main/kotlin/package.kt
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
10
mirai-core/src/linuxX64Test/kotlin/package.kt
Normal file
10
mirai-core/src/linuxX64Test/kotlin/package.kt
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
24
mirai-core/src/mingwX64Main/kotlin/MiraiImpl.kt
Normal file
24
mirai-core/src/mingwX64Main/kotlin/MiraiImpl.kt
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.curl.*
|
||||
import io.ktor.client.features.*
|
||||
|
||||
internal actual fun createDefaultHttpClient(): HttpClient {
|
||||
return HttpClient(Curl) {
|
||||
install(HttpTimeout) {
|
||||
this.requestTimeoutMillis = 30_0000
|
||||
this.connectTimeoutMillis = 30_0000
|
||||
this.socketTimeoutMillis = 30_0000
|
||||
}
|
||||
}
|
||||
}
|
10
mirai-core/src/mingwX64Main/kotlin/package.kt
Normal file
10
mirai-core/src/mingwX64Main/kotlin/package.kt
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
@ -19,16 +19,24 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory
|
||||
internal actual abstract class AbstractCommonNHTest actual constructor() :
|
||||
AbstractRealNetworkHandlerTest<TestCommonNetworkHandler>() {
|
||||
|
||||
actual override val network: TestCommonNetworkHandler
|
||||
get() = TODO("Not yet implemented")
|
||||
actual override val factory: NetworkHandlerFactory<TestCommonNetworkHandler>
|
||||
get() = TODO("Not yet implemented")
|
||||
actual override val network: TestCommonNetworkHandler by lazy {
|
||||
factory.create(createContext(), createAddress())
|
||||
}
|
||||
|
||||
actual override val factory: NetworkHandlerFactory<TestCommonNetworkHandler> =
|
||||
NetworkHandlerFactory<TestCommonNetworkHandler> { context, address ->
|
||||
object : TestCommonNetworkHandler(bot, context, address) {
|
||||
override suspend fun createConnection(): PlatformConn {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected actual fun removeOutgoingPacketEncoder() {
|
||||
}
|
||||
|
||||
actual val conn: PlatformConn
|
||||
get() = TODO("Not yet implemented")
|
||||
actual val conn: PlatformConn = PlatformConn()
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user