Skip to content

Commit 7866e44

Browse files
committed
feat(server): 实现服务器连接频率限制与封禁机制- 新增 BanManager.queryBanReason 方法用于查询封禁原因
- 在 ClientManager 中添加连接尝试计数器和时间窗口限制 - 实现 recordConnectionAttempt 方法检测频繁连接并自动封禁 - 修改握手处理逻辑,增加对频繁连接的封禁判断 - 更新日志记录格式,移除多余的 [Websocket] 前缀- 优化 Server_handle_ShakeHand 中的握手包发送逻辑 - 在 helpCommand 和 queryCommand 中添加封禁查询功能- 移除 ShadowJar 的最小化配置以避免依赖冲突 - 为 BotClient 添加独立的日志记录器- 调整常量命名规范并增强连接超时检测逻辑
1 parent c03c18e commit 7866e44

File tree

14 files changed

+186
-138
lines changed

14 files changed

+186
-138
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
# HuHoBot-Websocket-Kotlin v0.0.1
1+
# HuHoBot-Websocket-Kotlin v0.0.2
22

3-
- 初始化项目
3+
feat(server): 实现服务器连接频率限制与封禁机制- 新增 BanManager.queryBanReason 方法用于查询封禁原因
4+
- 在 ClientManager 中添加连接尝试计数器和时间窗口限制
5+
- 实现 recordConnectionAttempt 方法检测频繁连接并自动封禁
6+
- 修改握手处理逻辑,增加对频繁连接的封禁判断
7+
- 更新日志记录格式,移除多余的 [Websocket] 前缀- 优化 Server_handle_ShakeHand 中的握手包发送逻辑
8+
- 在 helpCommand 和 queryCommand 中添加封禁查询功能- 移除 ShadowJar 的最小化配置以避免依赖冲突
9+
- 为 BotClient 添加独立的日志记录器- 调整常量命名规范并增强连接超时检测逻辑
410

build.gradle.kts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
}
66

77
group = "cn.huohuas001"
8-
version = "0.0.1"
8+
version = "0.0.2"
99

1010
val kotlin = "2.2.20"
1111
val ktor = "3.3.0"
@@ -37,25 +37,6 @@ dependencies {
3737
testImplementation("io.ktor:ktor-server-test-host:$ktor")
3838
}
3939

40-
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
41-
// 启用最小化依赖
42-
minimize {
43-
exclude(dependency("org.slf4j:.*"))
44-
exclude(dependency("ch.qos.logback:.*"))
45-
}
46-
47-
// 排除不必要的文件
48-
exclude("META-INF/*.SF")
49-
exclude("META-INF/*.DSA")
50-
exclude("META-INF/*.RSA")
51-
exclude("META-INF/*.MF")
52-
53-
// 合并服务文件
54-
mergeServiceFiles()
55-
56-
// 压缩配置
57-
isZip64 = true
58-
}
5940

6041

6142

src/main/kotlin/WebsocketServer.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ object WebsocketServer {
9393
}
9494
}
9595
} catch (e: IOException) {
96-
logger.error("[Websocket] 关闭超时连接时出错", e)
96+
logger.error("关闭超时连接时出错", e)
9797
}
9898
}
9999
}
@@ -109,15 +109,15 @@ object WebsocketServer {
109109
val serverPackage = ClientManager.getServerPackageBySession(session)
110110
if (serverPackage != null) {
111111
if (ClientManager.isRegisteredServer(serverPackage.mServerId)) {
112-
logger.info("[Websocket] 客户端断开连接, ServerId: {}", serverPackage.mServerId)
112+
logger.info("客户端断开连接, ServerId: {}", serverPackage.mServerId)
113113
}
114114
ClientManager.unRegisterServer(serverPackage.mServerId)
115115
}
116116
}
117117

118118
fun handleError(session: WebSocketSession, error: Exception) {
119119
coroutineScope.launch { session.close(CloseReason(CloseReason.Codes.INTERNAL_ERROR, "Error Message.")) }
120-
logger.error("[Websocket] 处理消息时发生错误", error)
120+
logger.error("处理消息时发生错误", error)
121121
}
122122

123123
fun addCallback(id: String, callback: CompletableFuture<JSONObject>) {
@@ -162,14 +162,14 @@ object WebsocketServer {
162162
session.mSession.close(CloseReason(CloseReason.Codes.NORMAL, "无效的客户端连接"))
163163
}
164164
} catch (e: IOException) {
165-
logger.error("[Websocket] 处理无效客户端连接时发生错误:", e)
165+
logger.error("处理无效客户端连接时发生错误:", e)
166166
}
167167
return
168168
}
169169
val msgPack = ActionPack(eventType, body, packId, client)
170170
event.eventCall(msgPack)
171171
} else {
172-
logger.error("[Websocket] 未找到Server处理程序: {}", msgType)
172+
logger.error("未找到Server处理程序: {}", msgType)
173173
}
174174
}
175175

@@ -191,7 +191,7 @@ object WebsocketServer {
191191
val msgPack = ActionPack(eventType, body, packId, ClientManager.getBotClient())
192192
event.eventCall(msgPack)
193193
} else {
194-
logger.error("[Websocket] 未找到Bot处理程序: {}", msgType)
194+
logger.error("未找到Bot处理程序: {}", msgType)
195195
}
196196
}
197197

@@ -204,13 +204,13 @@ object WebsocketServer {
204204
val packId = header.getString("id")
205205

206206
if(msgType == null || packId == null){
207-
logger.error("[Websocket] 收到无效的封包: {}", payload)
207+
logger.error("收到无效的封包: {}", payload)
208208
try {
209209
coroutineScope.launch {
210210
session.mSession.close(CloseReason(CloseReason.Codes.PROTOCOL_ERROR, "无效的封包"))
211211
}
212212
} catch (e: IOException) {
213-
logger.error("[Websocket] 处理无效封包时发生错误:", e)
213+
logger.error("处理无效封包时发生错误:", e)
214214
}
215215
return
216216
}
@@ -220,7 +220,7 @@ object WebsocketServer {
220220

221221
//执行回调消息
222222
if (responseFutureList.containsKey(packId)) {
223-
logger.debug("[Websocket] 收到response消息: {}", payload)
223+
logger.debug("收到response消息: {}", payload)
224224
logger.debug("处理事件回调 {}", packId)
225225
val responseFuture = responseFutureList[packId]
226226
if (responseFuture != null && !responseFuture.isDone) {
@@ -237,7 +237,7 @@ object WebsocketServer {
237237
handleServerMessage(session, messagePack)
238238
}
239239
} catch (e: Exception) {
240-
logger.error("[Websocket] 处理消息时发生错误", e)
240+
logger.error("处理消息时发生错误", e)
241241
}
242242
}
243243

src/main/kotlin/client/BaseClient.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import java.io.IOException
1515
abstract class BaseClient(session: ClientSession, clientType: ClientType) {
1616
private val coroutineScope = CoroutineScope(Dispatchers.Default)
1717
abstract var mClientType: ClientType
18-
abstract var mSession: ClientSession;
18+
abstract var mSession: ClientSession
1919

2020
open val logger: Logger = LoggerFactory.getLogger("BaseClient")
2121
open var mServerId: String = ""
@@ -69,14 +69,14 @@ abstract class BaseClient(session: ClientSession, clientType: ClientType) {
6969
return true
7070
} catch (e: IllegalStateException) {
7171
// 处理 TEXT_PARTIAL_WRITING 或其他状态异常
72-
logger.error("[Websocket] 发送消息时状态异常: {}", e.message)
72+
logger.error("发送消息时状态异常: {}", e.message)
7373
coroutineScope.launch {
7474
close(CloseReason.Codes.NORMAL, "Connection state invalid") // 主动关闭会话
7575
}
7676
return false
7777
} catch (e: IOException) {
7878
// 处理 Broken pipe 或其他 IO 错误
79-
logger.error("[Websocket] 发送消息失败: {}", e.message)
79+
logger.error("发送消息失败: {}", e.message)
8080
return false
8181
}
8282
}
@@ -114,22 +114,22 @@ abstract class BaseClient(session: ClientSession, clientType: ClientType) {
114114
*/
115115
fun close(code: CloseReason.Codes, reason: String) {
116116
try {
117-
val status: CloseReason = CloseReason(code, reason)
117+
val status = CloseReason(code, reason)
118118
if (isActive()) {
119119
coroutineScope.launch {
120120
mSession.mSession.close(status)
121121
}
122122

123123
if (ClientManager.isRegisteredServer(mServerId)) {
124-
logger.info("[Websocket] 服务端主动关闭连接, ServerId: {}", mServerId)
124+
logger.info("服务端主动关闭连接, ServerId: {}", mServerId)
125125
}
126126
} else {
127127
if (ClientManager.isRegisteredServer(mServerId)) {
128-
logger.info("[Websocket] 服务端主动关闭连接时发现客户端已离线, ServerId: {}", mServerId)
128+
logger.info("服务端主动关闭连接时发现客户端已离线, ServerId: {}", mServerId)
129129
}
130130
}
131131
} catch (e: IOException) {
132-
logger.error("[Websocket] 服务端主动关闭连接时发生错误:", e)
132+
logger.error("服务端主动关闭连接时发生错误:", e)
133133
}
134134
}
135135

src/main/kotlin/client/BotClient.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import cn.huohuas001.events.bot.EventEnum.BotClientSendEvent
55
import cn.huohuas001.tools.getPackID
66
import com.alibaba.fastjson2.JSONObject
77
import io.ktor.websocket.*
8+
import org.slf4j.Logger
9+
import org.slf4j.LoggerFactory
810
import java.util.concurrent.CompletableFuture
911

1012
class BotClient(
1113
override var mSession: ClientSession
1214
) : BaseClient(mSession, ClientType.Bot) {
1315
override var mClientType: ClientType = ClientType.Bot
16+
override val logger: Logger = LoggerFactory.getLogger("BotClient")
1417

1518
/**
1619
* 发送消息
@@ -38,7 +41,6 @@ class BotClient(
3841
* 发送请求并等待响应
3942
* @param type 消息类型
4043
* @param body 消息内容
41-
* @param packId 包id
4244
* @return 响应结果
4345
*/
4446
fun sendRequestAndAwaitResponse(type: BotClientSendEvent, body: JSONObject): CompletableFuture<JSONObject> {

src/main/kotlin/command/helpCommand.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ object helpCommand: BaseCommand() {
77
override val logger: Logger = LoggerFactory.getLogger("helpCommand")
88
override fun run(args: MutableList<String>): Boolean {
99
logger.info("可用指令:")
10-
logger.info(" help - 显示帮助信息")
11-
logger.info(" exit - 退出应用程序")
12-
logger.info(" ban - 封禁服务器")
13-
logger.info(" unban - 解封服务器")
14-
logger.info(" list - 查看链接数量")
10+
logger.info(" help - 显示帮助信息")
11+
logger.info(" exit - 退出应用程序")
12+
logger.info(" ban - 封禁服务器")
13+
logger.info(" unban - 解封服务器")
14+
logger.info(" list - 查看链接数量")
1515
logger.info(" shutdown - 关闭服务器")
16+
logger.info(" query - 查询在线服务器或封禁原因")
1617
return true
1718
}
1819
}

src/main/kotlin/command/queryCommand.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.huohuas001.command
22

3+
import cn.huohuas001.tools.manager.BanManager
34
import cn.huohuas001.tools.manager.ClientManager
45
import org.slf4j.Logger
56
import org.slf4j.LoggerFactory
@@ -13,9 +14,15 @@ object queryCommand: BaseCommand() {
1314
}
1415

1516
val serverId = args[0]
16-
val serverPackage = ClientManager.getServerPackageById(serverId);
17-
if(serverPackage?.mServerClient == null){
18-
logger.info("未查找到 $serverId 的服务器")
17+
val serverPackage = ClientManager.getServerPackageById(serverId)
18+
19+
if(BanManager.queryBanReason(serverId) != null){
20+
logger.info("服务器 $serverId 已被封禁,封禁理由为: ${BanManager.queryBanReason(serverId)}")
21+
return false
22+
}
23+
24+
if(serverPackage.mServerClient == null){
25+
logger.warn("未查找到 $serverId 的服务器")
1926
return false
2027
}
2128
logger.info("服务器 $serverId 的详细为: ${serverPackage.mServerClient.name}|${serverPackage.mServerClient.version}|${serverPackage.mServerClient.platform}|${serverPackage.mServerClient.mSession.mIp}")

src/main/kotlin/events/bot/EventHandler/Bot_handle_QueryClientList.kt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,25 @@ object Bot_handle_QueryClientList: BaseEvent() {
1919
return false
2020
}
2121

22-
// 2. 使用Java Stream API优化集合操作
23-
val clientList = serverIdList.stream()
24-
.filter { serverId: Any? -> serverId is String }
25-
.map<String?> { serverId: Any -> serverId as String }
26-
.map<String?> { serverIdStr: String ->
27-
val clientName: String? = ClientManager.queryOnlineClient(serverIdStr)
28-
clientName ?: "Unknown Server" // 处理可能的null返回值
29-
}
30-
.collect(
31-
{ JSONArray() },
32-
BiConsumer { obj: JSONArray?, e: String? -> obj!!.add(e) },
33-
{ obj: JSONArray?, c: JSONArray? -> obj!!.addAll(c!!) })
22+
//如果是query MainServer
23+
var clientList = JSONArray()
24+
if(serverIdList.size == 1 && serverIdList.getString(0) == "MainServer"){
25+
val clientName = "MainServer 已连接.\n${ClientManager.queryOnlineClientCount()}个服务器在线."
26+
clientList.add(clientName)
27+
}else{
28+
// 使用Java Stream API优化集合操作
29+
clientList = serverIdList.stream()
30+
.filter { serverId: Any? -> serverId is String }
31+
.map<String?> { serverId: Any -> serverId as String }
32+
.map<String?> { serverIdStr: String ->
33+
val clientName: String = ClientManager.queryOnlineClient(serverIdStr)
34+
clientName
35+
}
36+
.collect(
37+
{ JSONArray() },
38+
BiConsumer { obj: JSONArray?, e: String? -> obj!!.add(e) },
39+
{ obj: JSONArray?, c: JSONArray? -> obj!!.addAll(c!!) })
40+
}
3441

3542
// 3. 构造响应
3643
val response = JSONObject()

src/main/kotlin/events/bot/EventHandler/Bot_handle_SendPack2Server.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ object Bot_handle_SendPack2Server: BaseEvent() {
1919
val data: JSONObject = mBody.getJSONObject("data")
2020

2121
// 2. 获取客户端实例(避免重复调用)
22-
val serverPack: ServerPack? = ClientManager.getServerPackageById(serverId)
23-
val serverClient: ServerClient? = serverPack?.mServerClient
22+
val serverPack: ServerPack = ClientManager.getServerPackageById(serverId)
23+
val serverClient: ServerClient? = serverPack.mServerClient
2424

2525
// 3. 构造响应状态包
2626
val statusPack = JSONObject()
@@ -31,9 +31,9 @@ object Bot_handle_SendPack2Server: BaseEvent() {
3131
try {
3232
status = serverClient.sendMessage(getServerSendEvent( type), data, mPackId)
3333
} catch (e: IllegalArgumentException) {
34-
logger.error("Invalid event type: {}", type, e)
34+
logger.error("未知的类型: {}", type, e)
3535
} catch (e: Exception) {
36-
logger.error("Failed to send message to server", e)
36+
logger.error("无法发送数据给服务器", e)
3737
}
3838
}
3939

@@ -42,12 +42,12 @@ object Bot_handle_SendPack2Server: BaseEvent() {
4242
if (botClient != null) {
4343
botClient!!.sendMessage(BotClientSendEvent.BotCallBack, statusPack, mPackId)
4444
} else {
45-
logger.warn("BotClient is null, cannot send callback")
45+
logger.warn("BotClient为空,不能回调")
4646
}
4747

4848
return true
4949
} catch (e: Exception) {
50-
logger.error("Error in Bot_handleSendPack2Server", e)
50+
logger.error("BotClient处理回调时发生了错误", e)
5151
return false
5252
}
5353
}

src/main/kotlin/events/bot/EventHandler/Bot_handle_ShakeHand.kt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package events.bot;
1+
package events.bot
22

33
import cn.huohuas001.client.BotClient
44
import cn.huohuas001.client.ClientSession
@@ -14,8 +14,8 @@ import org.slf4j.LoggerFactory
1414

1515
object Bot_handle_ShakeHand: BaseEvent() {
1616
override val logger: Logger = LoggerFactory.getLogger("Bot_handle_ShakeHand")
17-
override fun run(): Boolean?{
18-
return false;
17+
override fun run(): Boolean{
18+
return false
1919
}
2020

2121
private fun botClientConnect(session: ClientSession, serverId: String, hashKey: String) {
@@ -27,7 +27,7 @@ object Bot_handle_ShakeHand: BaseEvent() {
2727
shakeHandPack["code"] = 1
2828
shakeHandPack["msg"] = ""
2929
botClient.sendMessage(BotClientSendEvent.BotShook, shakeHandPack)
30-
logger.info("[Websocket] HuHoBot BotClient 已连接.")
30+
logger.info("HuHoBot BotClient 已连接.")
3131

3232
//重新清空WaitingList
3333
ClientManager.reShakeWaitingServer()
@@ -37,10 +37,6 @@ object Bot_handle_ShakeHand: BaseEvent() {
3737
val serverId: String = mBody.getString("serverId")
3838
val hashKey: String = mBody.getString("hashKey")
3939

40-
val platform: String? = mBody.getString("platform")
41-
val name: String? = mBody.getString("name")
42-
val version: String? = mBody.getString("version")
43-
4440
val shakeHandPack = JSONObject()
4541
val _botClient = BotClient(session)
4642

0 commit comments

Comments
 (0)