1
1
package cn.evolvefield.onebot.client.connection
2
2
3
- import cn.evole.onebot.sdk.util.json.JsonsObject
4
3
import cn.evolvefield.onebot.client.core.Bot
5
4
import cn.evolvefield.onebot.client.handler.ActionHandler
6
- import cn.evolvefield.onebot.client.handler.EventBus
7
- import cn.evolvefield.onebot.client.util.ActionSendUtils
8
- import com.google.gson.JsonSyntaxException
9
5
import kotlinx.coroutines.*
10
- import kotlinx.coroutines.sync.Mutex
11
- import kotlinx.coroutines.sync.withLock
12
6
import org.java_websocket.client.WebSocketClient
13
7
import org.java_websocket.framing.CloseFrame
14
8
import org.java_websocket.handshake.ServerHandshake
15
9
import org.slf4j.Logger
16
10
import java.net.URI
17
- import kotlin.math.log
18
11
19
12
/* *
20
13
* Project: onebot-client
@@ -23,26 +16,21 @@ import kotlin.math.log
23
16
* Description:
24
17
*/
25
18
class WSClient (
26
- private val scope : CoroutineScope ,
19
+ override val scope : CoroutineScope ,
27
20
uri : URI ,
28
- private val logger : Logger ,
29
- private val actionHandler : ActionHandler ,
30
- val retryTimes : Int = 5 ,
31
- val retryWaitMills : Long = 5000L ,
32
- val retryRestMills : Long = 60000L ,
21
+ override val logger : Logger ,
22
+ override val actionHandler : ActionHandler ,
23
+ private val retryTimes : Int = 5 ,
24
+ private val retryWaitMills : Long = 5000L ,
25
+ private val retryRestMills : Long = 60000L ,
33
26
header : Map <String , String > = mapOf(),
34
- ) : WebSocketClient(uri, header) {
27
+ ) : WebSocketClient(uri, header), IAdapter {
35
28
private var retryCount = 0
36
- private var eventBus: EventBus ? = null
37
- val connectDef = CompletableDeferred <Boolean >()
29
+ private val connectDef = CompletableDeferred <Boolean >()
38
30
fun createBot (): Bot {
39
31
return Bot (this , actionHandler)
40
32
}
41
33
42
- fun createEventBus (): EventBus {
43
- return if (eventBus != null ) eventBus!! else EventBus ().also { eventBus = it }
44
- }
45
-
46
34
suspend fun connectSuspend (): Boolean {
47
35
if (super .connectBlocking()) return true
48
36
return connectDef.await()
@@ -52,61 +40,44 @@ class WSClient(
52
40
logger.info(" ▌ 已连接到服务器 ┈━═☆" )
53
41
}
54
42
55
- override fun onMessage (message : String ) {
56
- try {
57
- val jsonObject = JsonsObject (message)
58
- if (HEART_BEAT != jsonObject.optString(META_EVENT )) { // 过滤心跳
59
- logger.debug(" Client received <-- {}" , jsonObject.toString())
60
- if (jsonObject.has(API_RESULT_KEY )) {
61
- actionHandler.onReceiveActionResp(jsonObject) // 请求执行
62
- } else {
63
- scope.launch {
64
- mutex.withLock {
65
- eventBus?.onReceive(message)
66
- }
67
- }
68
- }
69
- }
70
- } catch (e: JsonSyntaxException ) {
71
- logger.error(" Json语法错误:{}" , message)
72
- }
73
- }
43
+ override fun onMessage (message : String ) = onReceiveMessage(message)
74
44
75
45
override fun onClose (code : Int , reason : String , remote : Boolean ) {
76
46
logger.info(
77
47
" ▌ 服务器连接因 {} 已关闭 (关闭码: {})" ,
78
48
reason.ifEmpty { " 未知原因" },
79
49
CloseCode .valueOf(code) ? : code
80
50
)
81
- runCatching {
82
- if (mutex.isLocked) mutex.unlock()
83
- if (ActionSendUtils .mutex.isLocked) ActionSendUtils .mutex.unlock()
51
+ unlockMutex()
52
+
53
+ // 自动重连
54
+ if (code != CloseFrame .NORMAL ) retry()
55
+ }
56
+
57
+ private fun retry () {
58
+ if (retryTimes < 1 || retryWaitMills < 0 ) {
59
+ logger.warn(" 连接失败,未开启自动重连,放弃连接" )
60
+ connectDef.complete(false )
61
+ return
84
62
}
85
- if (code != CloseFrame .NORMAL ) { // TODO: 测试确认异常关闭码
86
- if (retryTimes < 1 || retryWaitMills < 0 ) {
87
- logger.warn(" 连接失败,未开启自动重连,放弃连接" )
88
- connectDef.complete(false )
89
- return
90
- }
91
- scope.launch {
92
- if (retryCount < retryTimes) {
93
- retryCount++
94
- logger.warn(" 等待 ${String .format(" %.1f" , retryWaitMills / 1000.0F )} 秒后重连 (第 $retryCount /$retryTimes 次)" )
95
- delay(retryWaitMills)
96
- } else {
97
- retryCount = 0
98
- if (retryRestMills < 0 ) {
99
- logger.warn(" 重连次数耗尽... 放弃重试" )
100
- return @launch
101
- }
102
- logger.warn(" 重连次数耗尽... 休息 ${String .format(" %.1f" , retryRestMills / 1000.0F )} 秒后重试" )
103
- delay(retryRestMills)
104
- }
105
- logger.info(" 正在重连..." )
106
- if (reconnectBlocking()) {
107
- retryCount = 0
108
- connectDef.complete(true )
63
+ scope.launch {
64
+ if (retryCount < retryTimes) {
65
+ retryCount++
66
+ logger.warn(" 等待 ${String .format(" %.1f" , retryWaitMills / 1000.0F )} 秒后重连 (第 $retryCount /$retryTimes 次)" )
67
+ delay(retryWaitMills)
68
+ } else {
69
+ retryCount = 0
70
+ if (retryRestMills < 0 ) {
71
+ logger.warn(" 重连次数耗尽... 放弃重试" )
72
+ return @launch
109
73
}
74
+ logger.warn(" 重连次数耗尽... 休息 ${String .format(" %.1f" , retryRestMills / 1000.0F )} 秒后重试" )
75
+ delay(retryRestMills)
76
+ }
77
+ logger.info(" 正在重连..." )
78
+ if (reconnectBlocking()) {
79
+ retryCount = 0
80
+ connectDef.complete(true )
110
81
}
111
82
}
112
83
}
@@ -116,11 +87,6 @@ class WSClient(
116
87
}
117
88
118
89
companion object {
119
- private const val META_EVENT = " meta_event_type"
120
- private const val API_RESULT_KEY = " echo"
121
- private const val HEART_BEAT = " heartbeat"
122
-
123
- val mutex = Mutex ()
124
90
fun createAndConnect (scope : CoroutineScope , uri : URI , logger : Logger , actionHandler : ActionHandler , retryTimes : Int , retryWaitMills : Long , retryRestMills : Long , header : Map <String , String > = mapOf()): WSClient ? {
125
91
val ws = WSClient (scope, uri, logger, actionHandler, retryTimes, retryWaitMills, retryRestMills, header)
126
92
return ws.takeIf { runBlocking { ws.connectSuspend() } }
0 commit comments