From 9b047aba82c29837f5b9506679fb12181f1ad397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=94=E6=B0=91=E5=B0=8F=E9=95=87?= <262610965@qq.com> Date: Sat, 9 Nov 2024 18:04:39 +0800 Subject: [PATCH] :whale: feat(external): add SocketIdleExcludeHandler, If the server is not configured with heartbeat processing, exclude heartbeat data --- .../core/exception/ActionErrorEnum.java | 6 ++ .../concurrent/timer/delay/package-info.java | 10 ++-- .../core/hook/cache/InternalAboutCache.java | 11 +--- .../handler/SocketIdleExcludeHandler.java | 60 +++++++++++++++++++ .../netty/micro/SocketMicroBootstrapFlow.java | 6 +- 5 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/SocketIdleExcludeHandler.java diff --git a/common/common-core/src/main/java/com/iohao/game/action/skeleton/core/exception/ActionErrorEnum.java b/common/common-core/src/main/java/com/iohao/game/action/skeleton/core/exception/ActionErrorEnum.java index db9a851dd..d2484e49f 100644 --- a/common/common-core/src/main/java/com/iohao/game/action/skeleton/core/exception/ActionErrorEnum.java +++ b/common/common-core/src/main/java/com/iohao/game/action/skeleton/core/exception/ActionErrorEnum.java @@ -22,6 +22,8 @@ import lombok.Getter; import lombok.experimental.FieldDefaults; +import java.util.Locale; + /** * action 错误码 *
@@ -74,4 +76,8 @@ public enum ActionErrorEnum implements MsgExceptionInfo {
         this.code = code;
         this.msg = msg;
     }
+
+    public String getMsg() {
+        return Locale.getDefault() == Locale.CHINA ? msg : name();
+    }
 }
diff --git a/common/common-micro-kit/src/main/java/com/iohao/game/common/kit/concurrent/timer/delay/package-info.java b/common/common-micro-kit/src/main/java/com/iohao/game/common/kit/concurrent/timer/delay/package-info.java
index 71d8b2b06..080c7c0fb 100644
--- a/common/common-micro-kit/src/main/java/com/iohao/game/common/kit/concurrent/timer/delay/package-info.java
+++ b/common/common-micro-kit/src/main/java/com/iohao/game/common/kit/concurrent/timer/delay/package-info.java
@@ -26,11 +26,13 @@
  * 
* 轻量可控的延时任务 - 特点 *
- *     1. 任务到达指定时间后会执行
- *     2. 任务可取消
- *     3. 任务可增加、减少延时的时间
+ *     1. 单一职责原则
+ *     2. 任务到达指定时间后会执行
+ *     3. 任务可取消
  *     4. 任务可被覆盖
- *     5. 可设置任务监听回调
+ *     5. 任务可增加、减少延时的时间
+ *     6. 可设置任务监听回调
+ *     7. 内部使用 Netty HashedWheelTimer,轻松支持百万任务。
  * 
* for example *
{@code
diff --git a/external/external-core/src/main/java/com/iohao/game/external/core/hook/cache/InternalAboutCache.java b/external/external-core/src/main/java/com/iohao/game/external/core/hook/cache/InternalAboutCache.java
index 29387957e..57fbc76b2 100644
--- a/external/external-core/src/main/java/com/iohao/game/external/core/hook/cache/InternalAboutCache.java
+++ b/external/external-core/src/main/java/com/iohao/game/external/core/hook/cache/InternalAboutCache.java
@@ -233,23 +233,18 @@ final class CmdCacheRegion {
      */
     CmdActionCache getCmdCache(int cmdMerge) {
 
-        CmdActionCache cmdActionCache = this.cmdCacheMap.get(cmdMerge);
-
+        var cmdActionCache = this.cmdCacheMap.get(cmdMerge);
         if (Objects.nonNull(cmdActionCache)) {
             return cmdActionCache;
         }
 
         // 如果开启了范围缓存,即使没有显示的配置,也会生成缓存对象
-        if (range) {
-            cmdActionCache = addCmdCache(cmdMerge, this.cmdCacheOption);
-        }
-
-        return cmdActionCache;
+        return range ? addCmdCache(cmdMerge, this.cmdCacheOption) : null;
     }
 
     CmdActionCache addCmdCache(int cmdMerge, CmdCacheOption cmdCacheOption) {
 
-        CmdActionCache cmdActionCache = this.cmdCacheMap.get(cmdMerge);
+        var cmdActionCache = this.cmdCacheMap.get(cmdMerge);
         if (Objects.nonNull(cmdActionCache)) {
             return cmdActionCache;
         }
diff --git a/external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/SocketIdleExcludeHandler.java b/external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/SocketIdleExcludeHandler.java
new file mode 100644
index 000000000..29e45ef1f
--- /dev/null
+++ b/external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/SocketIdleExcludeHandler.java
@@ -0,0 +1,60 @@
+/*
+ * ioGame
+ * Copyright (C) 2021 - present  渔民小镇 (262610965@qq.com、luoyizhu@gmail.com) . All Rights Reserved.
+ * # iohao.com . 渔民小镇
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see .
+ */
+package com.iohao.game.external.core.netty.handler;
+
+import com.iohao.game.action.skeleton.protocol.BarMessage;
+import com.iohao.game.external.core.message.ExternalMessageCmdCode;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
+/**
+ * Exclude heartbeat message
+ *
+ * @author 渔民小镇
+ * @date 2024-11-09
+ * @since 21.20
+ */
+@ChannelHandler.Sharable
+public final class SocketIdleExcludeHandler extends ChannelInboundHandlerAdapter {
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        BarMessage message = (BarMessage) msg;
+
+        int cmdCode = message.getHeadMetadata().getCmdCode();
+        if (cmdCode == ExternalMessageCmdCode.idle) {
+            return;
+        }
+
+        // 交给下一个业务处理 (handler) , 下一个业务指的是你编排 handler 时的顺序
+        ctx.fireChannelRead(msg);
+    }
+
+    private SocketIdleExcludeHandler() {
+    }
+
+    public static SocketIdleExcludeHandler me() {
+        return Holder.ME;
+    }
+
+    /** 通过 JVM 的类加载机制, 保证只加载一次 (singleton) */
+    private static class Holder {
+        static final SocketIdleExcludeHandler ME = new SocketIdleExcludeHandler();
+    }
+}
diff --git a/external/external-netty/src/main/java/com/iohao/game/external/core/netty/micro/SocketMicroBootstrapFlow.java b/external/external-netty/src/main/java/com/iohao/game/external/core/netty/micro/SocketMicroBootstrapFlow.java
index bdf9df70e..cd763540a 100644
--- a/external/external-netty/src/main/java/com/iohao/game/external/core/netty/micro/SocketMicroBootstrapFlow.java
+++ b/external/external-netty/src/main/java/com/iohao/game/external/core/netty/micro/SocketMicroBootstrapFlow.java
@@ -60,6 +60,9 @@ protected void initChannel(SocketChannel ch) {
     public void pipelineIdle(PipelineContext context) {
         IdleProcessSetting idleProcessSetting = this.setting.getIdleProcessSetting();
         if (Objects.isNull(idleProcessSetting)) {
+            // 如果服务器没有配置心跳相关的内容,则排除心跳数据(不做任何处理)
+            // If the server is not configured with heartbeat processing, exclude heartbeat data
+            context.addLast("SocketIdleExcludeHandler", SocketIdleExcludeHandler.me());
             return;
         }
 
@@ -71,9 +74,8 @@ public void pipelineIdle(PipelineContext context) {
                 idleProcessSetting.getTimeUnit())
         );
 
-        SocketIdleHandler socketIdleHandler = setting.option(SettingOption.socketIdleHandler);
-
         // 心跳响应、心跳钩子 Handler
+        SocketIdleHandler socketIdleHandler = setting.option(SettingOption.socketIdleHandler);
         context.addLast("idleHandler", socketIdleHandler);
     }