simple-robot / simbot-component-onebot

一个Kotlin多平台的 OneBot SDK 实现,一个异步高效、Java 友好的 Simple Robot 组件库 ~ 🐱🐱🐱
https://simbot.forte.love/component-onebot.html
GNU Lesser General Public License v3.0
9 stars 3 forks source link

ws断掉之后,不会重连吗? #105

Closed kukume closed 2 weeks ago

kukume commented 2 weeks ago

是否会提供贡献?

版本信息

implementation("love.forte.simbot.component:simbot-component-onebot-v11-core:1.4.1")

涉及的编程语言

Kotlin

项目构建工具

Gradle

内容描述

在出现该错误后

Exception in thread "DefaultDispatcher-worker-1" java.io.EOFException
    at okio.RealBufferedSource.require(RealBufferedSource.kt:202)
    at okio.RealBufferedSource.readByte(RealBufferedSource.kt:212)
    at okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119)
    at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102)
    at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293)
    at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@48786039, Dispatchers.Default]

,机器人无响应,必须重启才能正常响应。 是否在ws出现意外断掉之后,不会重新链接?

ForteScarlet commented 2 weeks ago

断连后应当是有重连行为的,如果没有那有可能是bug,晚上看看

kukume commented 2 weeks ago

目前测试是没有重连机制的,在程序启动成功后,退出qq客户端,然后会出现上述错误,没有看到重连的日志,而且重新启动qq客户端,也没有重连的日志。已开启debug。 完整日志,从链接成功到断口链接,之后一直无日志

2024-09-06T02:31:00.296Z DEBUG 6601 --- [atcher-worker-2] l.f.s.c.o.v.c.bot.OneBotBot.qq    : Update bot login info: GetLoginInfoResult(userId=qq, nickname=‭‭‭‭‭‭‭‭‭‭‭‭)
2024-09-06T02:31:00.297Z DEBUG 6601 --- [atcher-worker-2] l.f.s.c.o.v.c.bot.OneBotBot.qq    : WebSocket connection is enabled to ws://ip:10304 via client HttpClient[io.ktor.client.engine.okhttp.OkHttpEngine@1a33f483]
2024-09-06T02:31:00.298Z DEBUG 6601 --- [atcher-worker-2] l.f.s.c.o.v.c.bot.OneBotBot.qq    : Connect to ws server ws://ip:10304
2024-09-06T02:31:01.903Z DEBUG 6601 --- [atcher-worker-3] l.f.s.c.o.v.c.bot.OneBotBot.qq    : WebSocket session connected: love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl$WsEventSession@3768451c
2024-09-06T02:31:01.904Z DEBUG 6601 --- [atcher-worker-1] l.f.s.c.o.v.c.bot.OneBotBot.qq    : Connected to ws server ws://ip:10304, session: io.ktor.client.plugins.websocket.DefaultClientWebSocketSession@6f87a5f8
2024-09-06T02:31:01.906Z DEBUG 6601 --- [atcher-worker-1] l.f.s.c.o.v.c.bot.OneBotBot.qq    : Received raw event: {"time":1725590939,"self_id":qq,"post_type":"meta_event","meta_event_type":"lifecycle","sub_type":"connect"}
2024-09-06T02:31:54.865Z DEBUG 6601 --- [atcher-worker-1] l.f.s.c.o.v.c.bot.OneBotBot.q    : Session received Close frame result: Closed(java.io.EOFException)
Exception in thread "DefaultDispatcher-worker-1" java.io.EOFException
    at okio.RealBufferedSource.require(RealBufferedSource.kt:202)
    at okio.RealBufferedSource.readByte(RealBufferedSource.kt:212)
    at okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119)
    at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102)
    at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293)
    at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@628ef79, Dispatchers.Default]
ForteScarlet commented 2 weeks ago

从这里来看, https://github.com/simple-robot/simbot-component-onebot/blob/1b4cc2a32208cc300e0655aadd6e0395f6d3fa09/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt#L319-L364 重连机制是有的,createSessionWithRetry 在创建连接时会根据配置重连,连接后如果连接被关闭(也就是日志中出现了 Session received Close frame result: xxx)时,receiveEvent 将会结束,并在 sessionJob 仍然存活时应在 launch 中继续尝试重新连接。

不过根据你的描述,似乎没有出现 sessionJob 在结束生命时候会出现的日志 Job is completed: xxx,我会先尝试一下本地复现此问题

kukume commented 2 weeks ago

提交pr了。在停止的时候重新执行start。 debug是在429行会抛出异常,launch函数会直接退出,后续没有反应了。

ForteScarlet commented 2 weeks ago

嗯pr我看到了,不过如果是 429 行的错误,https://github.com/simple-robot/simbot-component-onebot/blob/1b4cc2a32208cc300e0655aadd6e0395f6d3fa09/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt#L429 根据KDoc的描述,closeReason.await 的确可能会产生 CancellationException,这部分确实疏忽了,如果仅捕获此处即能解决的话最好,可以简单调整下 pr 我会测试一下,然后在 #106 再进行评论补充

kukume commented 2 weeks ago

直接catch可以重连,重新提交了

ForteScarlet commented 2 weeks ago

OK 👌 顺带一提,刚刚做测试时,如果 ktor 引擎选择的 client-java 则不会出现 EOF 这个异常,可以正常重连,如有需要可以在修复版本发布之前做临时处理