Skip to content

Commit 3ecc323

Browse files
committed
EventBus should be object for multi bot support
1 parent 004f495 commit 3ecc323

File tree

9 files changed

+158
-186
lines changed

9 files changed

+158
-186
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cn.evolvefield.onebot.client.connection
2+
3+
import cn.evole.onebot.sdk.util.json.JsonsObject
4+
import cn.evolvefield.onebot.client.handler.ActionHandler
5+
import cn.evolvefield.onebot.client.handler.EventBus
6+
import cn.evolvefield.onebot.client.util.ActionSendUtils
7+
import com.google.gson.JsonSyntaxException
8+
import kotlinx.coroutines.CoroutineScope
9+
import kotlinx.coroutines.launch
10+
import kotlinx.coroutines.sync.Mutex
11+
import kotlinx.coroutines.sync.withLock
12+
import org.slf4j.Logger
13+
14+
interface IAdapter {
15+
val scope: CoroutineScope
16+
val actionHandler: ActionHandler
17+
val logger: Logger
18+
19+
fun onReceiveMessage(message: String) {
20+
try {
21+
val json = JsonsObject(message)
22+
if (json.optString(META_EVENT) != HEART_BEAT) { // 过滤心跳
23+
logger.debug("Client received <-- {}", json.toString())
24+
25+
if (json.has(API_RESULT_KEY)) { // 接口回调
26+
actionHandler.onReceiveActionResp(json)
27+
} else scope.launch { // 处理事件
28+
mutex.withLock {
29+
EventBus.onReceive(message)
30+
}
31+
}
32+
}
33+
} catch (e: JsonSyntaxException) {
34+
logger.error("Json语法错误: {}", message)
35+
}
36+
}
37+
38+
fun unlockMutex() {
39+
runCatching {
40+
if (mutex.isLocked) mutex.unlock()
41+
if (ActionSendUtils.mutex.isLocked) ActionSendUtils.mutex.unlock()
42+
}
43+
}
44+
45+
companion object {
46+
private const val META_EVENT = "meta_event_type"
47+
private const val API_RESULT_KEY = "echo"
48+
private const val HEART_BEAT = "heartbeat"
49+
50+
val mutex = Mutex()
51+
}
52+
}

onebot/src/main/kotlin/cn/evolvefield/onebot/client/connection/WSClient.kt

Lines changed: 37 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
package cn.evolvefield.onebot.client.connection
22

3-
import cn.evole.onebot.sdk.util.json.JsonsObject
43
import cn.evolvefield.onebot.client.core.Bot
54
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
95
import kotlinx.coroutines.*
10-
import kotlinx.coroutines.sync.Mutex
11-
import kotlinx.coroutines.sync.withLock
126
import org.java_websocket.client.WebSocketClient
137
import org.java_websocket.framing.CloseFrame
148
import org.java_websocket.handshake.ServerHandshake
159
import org.slf4j.Logger
1610
import java.net.URI
17-
import kotlin.math.log
1811

1912
/**
2013
* Project: onebot-client
@@ -23,26 +16,21 @@ import kotlin.math.log
2316
* Description:
2417
*/
2518
class WSClient(
26-
private val scope: CoroutineScope,
19+
override val scope: CoroutineScope,
2720
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,
3326
header: Map<String, String> = mapOf(),
34-
) : WebSocketClient(uri, header) {
27+
) : WebSocketClient(uri, header), IAdapter {
3528
private var retryCount = 0
36-
private var eventBus: EventBus? = null
37-
val connectDef = CompletableDeferred<Boolean>()
29+
private val connectDef = CompletableDeferred<Boolean>()
3830
fun createBot(): Bot {
3931
return Bot(this, actionHandler)
4032
}
4133

42-
fun createEventBus(): EventBus {
43-
return if (eventBus != null) eventBus!! else EventBus().also { eventBus = it }
44-
}
45-
4634
suspend fun connectSuspend(): Boolean {
4735
if (super.connectBlocking()) return true
4836
return connectDef.await()
@@ -52,61 +40,44 @@ class WSClient(
5240
logger.info("▌ 已连接到服务器 ┈━═☆")
5341
}
5442

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)
7444

7545
override fun onClose(code: Int, reason: String, remote: Boolean) {
7646
logger.info(
7747
"▌ 服务器连接因 {} 已关闭 (关闭码: {})",
7848
reason.ifEmpty { "未知原因" },
7949
CloseCode.valueOf(code) ?: code
8050
)
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
8462
}
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
10973
}
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)
11081
}
11182
}
11283
}
@@ -116,11 +87,6 @@ class WSClient(
11687
}
11788

11889
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()
12490
fun createAndConnect(scope: CoroutineScope, uri: URI, logger: Logger, actionHandler: ActionHandler, retryTimes: Int, retryWaitMills: Long, retryRestMills: Long, header: Map<String, String> = mapOf()): WSClient? {
12591
val ws = WSClient(scope, uri, logger, actionHandler, retryTimes, retryWaitMills, retryRestMills, header)
12692
return ws.takeIf { runBlocking { ws.connectSuspend() } }

onebot/src/main/kotlin/cn/evolvefield/onebot/client/connection/WSServer.kt

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
package cn.evolvefield.onebot.client.connection
22

3-
import cn.evole.onebot.sdk.util.json.JsonsObject
43
import cn.evolvefield.onebot.client.core.Bot
54
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
95
import kotlinx.coroutines.CompletableDeferred
106
import kotlinx.coroutines.CoroutineScope
11-
import kotlinx.coroutines.launch
12-
import kotlinx.coroutines.sync.Mutex
13-
import kotlinx.coroutines.sync.withLock
147
import org.java_websocket.WebSocket
158
import org.java_websocket.framing.CloseFrame
169
import org.java_websocket.handshake.ClientHandshake
@@ -25,20 +18,15 @@ import java.net.InetSocketAddress
2518
* Description:
2619
*/
2720
class WSServer(
28-
private val scope: CoroutineScope,
21+
override val scope: CoroutineScope,
2922
address: InetSocketAddress,
30-
private val logger: Logger,
31-
private val actionHandler: ActionHandler,
23+
override val logger: Logger,
24+
override val actionHandler: ActionHandler,
3225
private val token: String
33-
) : WebSocketServer(address) {
34-
private var eventBus: EventBus? = null
26+
) : WebSocketServer(address), IAdapter {
3527
private var bot: Bot? = null
3628
val def = CompletableDeferred<Bot>()
3729

38-
fun createEventBus(): EventBus {
39-
return if (eventBus != null) eventBus!! else EventBus().also { eventBus = it }
40-
}
41-
4230
override fun onStart() {
4331
logger.info("▌ 反向 WebSocket 服务端已在 $address 启动")
4432
logger.info("▌ 正在等待客户端连接...")
@@ -76,48 +64,22 @@ class WSServer(
7664
}).conn = conn
7765
}
7866

79-
override fun onMessage(conn: WebSocket, message: String) {
80-
try {
81-
val jsonObject = JsonsObject(message)
82-
if (HEART_BEAT != jsonObject.optString(META_EVENT)) { //过滤心跳
83-
logger.debug("Client received <-- {}", jsonObject.toString())
84-
if (jsonObject.has(API_RESULT_KEY)) {
85-
actionHandler.onReceiveActionResp(jsonObject) //请求执行
86-
} else {
87-
scope.launch {
88-
mutex.withLock {
89-
eventBus?.onReceive(message)
90-
}
91-
}
92-
}
93-
}
94-
} catch (e: JsonSyntaxException) {
95-
logger.error("Json语法错误: {}", message)
96-
}
97-
}
67+
override fun onMessage(conn: WebSocket, message: String) = onReceiveMessage(message)
9868

9969
override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) {
10070
logger.info(
10171
"▌ 反向 WebSocket 客户端连接因 {} 已关闭 (关闭码: {})",
10272
reason.ifEmpty { "未知原因" },
10373
CloseCode.valueOf(code) ?: code
10474
)
105-
runCatching {
106-
if (mutex.isLocked) mutex.unlock()
107-
if (ActionSendUtils.mutex.isLocked) ActionSendUtils.mutex.unlock()
108-
}
75+
unlockMutex()
10976
}
11077

11178
override fun onError(conn: WebSocket, ex: Exception) {
11279
logger.error("▌ 反向 WebSocket 客户端连接出现错误 {} 或未连接 ┈━═☆", ex.localizedMessage)
11380
}
11481

11582
companion object {
116-
private const val META_EVENT = "meta_event_type"
117-
private const val API_RESULT_KEY = "echo"
118-
private const val HEART_BEAT = "heartbeat"
119-
120-
val mutex = Mutex()
12183
suspend fun createAndWaitConnect(scope: CoroutineScope, address: InetSocketAddress, logger: Logger, actionHandler: ActionHandler, token: String): Pair<WSServer, Bot> {
12284
val ws = WSServer(scope, address, logger, actionHandler, token)
12385
ws.start()

onebot/src/main/kotlin/cn/evolvefield/onebot/client/handler/EventBus.kt

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,20 @@ import java.util.concurrent.ConcurrentHashMap
1515
* Description:
1616
*/
1717
@Suppress("unused")
18-
class EventBus {
19-
18+
object EventBus {
19+
private val log = LoggerFactory.getLogger(EventBus::class.java)
2020
//存储监听器对象
21-
private val eventlistenerlist: MutableList<EventListener<out Event>> = ArrayList()
22-
21+
private val listeners: MutableList<EventListener<out Event>> = ArrayList()
2322
//缓存类型与监听器的关系
2423
private val cache: MutableMap<Class<out Event>, List<EventListener<out Event>>> = ConcurrentHashMap()
2524

2625
fun addListener(listener: EventListener<out Event>) {
27-
eventlistenerlist.add(listener)
26+
listeners.add(listener)
2827
}
2928

3029
fun stop() {
3130
cache.clear()
32-
eventlistenerlist.clear()
31+
listeners.clear()
3332
}
3433

3534
/**
@@ -63,7 +62,7 @@ class EventBus {
6362
*/
6463
private fun getMethod(messageType: Class<out Event>): List<EventListener<out Event>> {
6564
val eventListeners: MutableList<EventListener<out Event>> = ArrayList()
66-
for (eventListener in eventlistenerlist) {
65+
for (eventListener in listeners) {
6766
try {
6867
if (eventListener.javaClass.declaredMethods.none {
6968
it.name == "onMessage" && it.parameterTypes.any { par -> messageType == par }
@@ -78,16 +77,12 @@ class EventBus {
7877
}
7978

8079
val listenerList: List<EventListener<out Event>>
81-
get() = eventlistenerlist
80+
get() = listeners
8281

8382
/**
8483
* 清除类型缓存
8584
*/
8685
fun cleanCache() {
8786
cache.clear()
8887
}
89-
90-
companion object {
91-
private val log = LoggerFactory.getLogger(EventBus::class.java)
92-
}
9388
}

0 commit comments

Comments
 (0)