Skip to content

Commit

Permalink
修复在反向ws模式下,由于重新设置wrapper时的作用域问题导致无法获取好友列表的问题 (#97)
Browse files Browse the repository at this point in the history
* fix: 🐛 修复反向ws,bot重新连接时,由于wrapper impl设置错误导致无法获取新bot的bug
feat: ✨ 为OneBot库添加测试时日志支持

* fix: 🐛 修复测试api引入错误问题

* build: ➖ 将logback挪到testImpl
  • Loading branch information
kagg886 authored Sep 15, 2024
1 parent 674658e commit d6669df
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 5 deletions.
1 change: 1 addition & 0 deletions onebot/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies {
annotationProcessor("org.java-websocket:Java-WebSocket:1.5.7")
annotationProcessor("org.projectlombok:lombok:1.18.26")
testCompileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4")
testImplementation("ch.qos.logback:logback-classic:1.4.14")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation(kotlin("test"))
}
28 changes: 24 additions & 4 deletions onebot/src/main/kotlin/client/connection/WSServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.java_websocket.server.DefaultWebSocketServerFactory
import org.java_websocket.server.WebSocketServer
import org.slf4j.Logger
import java.net.InetSocketAddress
import kotlin.random.Random
import kotlin.time.Duration

/**
Expand All @@ -25,6 +26,7 @@ import kotlin.time.Duration
* Date: 2023/12/4 8:36
* Description:
*/
val random = Random(System.currentTimeMillis())
class WSServer(
override val scope: CoroutineScope,
private val config: BotConfig,
Expand All @@ -34,8 +36,24 @@ class WSServer(
private val token: String
) : WebSocketServer(address), IAdapter {
// private var bot: Bot? = null
data class BotWrapper(
val bot:Bot
) {
private val hashCode by lazy {
random.nextInt()
}
override fun equals(other: Any?): Boolean {
return hashCode() == other?.hashCode()
}

override fun hashCode(): Int {
return hashCode
}
}

private val bots: MutableList<Bot> = mutableListOf()
private val botChannel = Channel<Bot>()
//通过使Wrapper互不相等,使得当bot重新上线时,botChannel推送成功。
private val botChannel = Channel<BotWrapper>()
private val muteX = Mutex()
val connectDef = CompletableDeferred<Bot>(config.parentJob)

Expand All @@ -59,7 +77,7 @@ class WSServer(

suspend fun awaitNewBot(timeout: Duration = Duration.INFINITE): Bot {
return withTimeout(timeout) {
botChannel.receive()
botChannel.receive().bot
}
}

Expand Down Expand Up @@ -93,7 +111,7 @@ class WSServer(
}
}
bots.add(bot)
botChannel.send(bot)
botChannel.send(BotWrapper(bot))
}
}

Expand All @@ -108,7 +126,9 @@ class WSServer(
unlockMutex()
runBlocking {
muteX.withLock {
bots.removeIf { it.conn == conn }
if (!bots.removeIf { it.conn == conn }) {
logger.warn("bot移除失败,这并不应该被发生。")
}
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions onebot/src/test/java/client/connection/OneBotProducerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ import kotlin.time.Duration.Companion.seconds

class OneBotProducerTest {

/**
* 请勿在CI里使用该test。
* 启动反向ws实例,强行停止后再次connect,awaitNewBotConnection()应该会返回一个bot链接。
* 这个bot的id是懒加载的,这个我也不太清楚
*/
@Test
fun `test connection no mock`(): Unit = runBlocking {
val producer = ConnectFactory.create(
BotConfig(
reversedPort = 3001
)
).createProducer()
while (true) {
println("waiting connect")
val bot = producer.awaitNewBotConnection()
println("新bot加入连接:${bot?.id}")
}
}

@Test
fun `positive connection should be connect once`(): Unit = runBlocking {
val job1 = launch {
Expand Down Expand Up @@ -64,6 +83,7 @@ class OneBotProducerTest {
}
jobs.join()
}

@Test
fun `should be called when server closing`(): Unit = runBlocking {
val factory = ConnectFactory.create(
Expand Down
13 changes: 13 additions & 0 deletions onebot/src/test/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.netty" level="INFO"/>
</configuration>
8 changes: 8 additions & 0 deletions overflow-core-all/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ setupMavenCentralPublication {
artifact(tasks.kotlinSourcesJar)
}

tasks.test {
useJUnitPlatform()
}

dependencies {
api(project(":onebot"))
api(project(":overflow-core-api"))
api(project(":overflow-core"))
testCompileOnly("net.mamoe:mirai-core-api:2.16.0")

testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
}

tasks {
Expand Down
25 changes: 25 additions & 0 deletions overflow-core-all/src/test/kotlin/OverFlowTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.syncFromEvent
import org.junit.jupiter.api.Test
import top.mrxiaom.overflow.BotBuilder

class OverFlowTest {
@Test
fun `should be reconnect successfully`(): Unit = runBlocking {
val builder = BotBuilder.reversed(3001)

while (true) {
println("等待连接中...")
val bot = builder.connect()
if (bot !== null) {
println("新bot加入连接:${bot}")
//确保重新连接后event可以正常接收
//这里建议使用GlobalEventChannel避免重复注册的问题
bot.eventChannel.subscribeAlways<GroupMessageEvent> {
println(it)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,13 @@ internal class BotWrapper private constructor(
configuration: BotConfiguration? = null,
workingDir: (Long.() -> File)? = null
): BotWrapper {
val newBot = this
// also refresh bot id
val result = getLoginInfo()
val json = result.json.data ?: JsonObject()
val loginInfo = result.data ?: throw IllegalStateException("无法获取机器人账号信息")
return (net.mamoe.mirai.Bot.getInstanceOrNull(id) as? BotWrapper)?.apply {
implBot = impl
implBot = newBot
updateContacts()
} ?: run {
val botConfiguration = configuration ?: defaultBotConfiguration
Expand Down

0 comments on commit d6669df

Please sign in to comment.