浏览代码

增加WS请求响应对象池

johnclot69 3 月之前
父节点
当前提交
b0c4c2e2a9

+ 7 - 0
incubator-core/src/main/java/com/incubator/core/net/ws/MsgBase.java

@@ -64,6 +64,13 @@ public abstract class MsgBase {
         return JSON.toJSONString(this);
     }
 
+    public void reset() {
+        this.cmd = 0;
+        this.code = 0;
+        this.message = "";
+        this.data.clear();
+    }
+
     /**
      * 从字节数组反序列化为 WSRequest 对象
      */

+ 24 - 0
incubator-core/src/main/java/com/incubator/core/pool/WSRequestPool.java

@@ -0,0 +1,24 @@
+package com.incubator.core.pool;
+
+import com.incubator.core.net.ws.WSRequest;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public final class WSRequestPool {
+
+    private static final ConcurrentLinkedQueue<WSRequest> requestPool = new ConcurrentLinkedQueue<>();
+
+    public static WSRequest getRequest(byte[] bytes) throws Exception {
+        WSRequest request = requestPool.poll();
+        if (request == null) {
+            request = new WSRequest(); // 初始化
+        }
+        request.fromBytes(bytes); // 重新初始化数据
+        return request;
+    }
+
+    public static void recycle(WSRequest request) {
+        request.reset(); // 重置状态,防止脏数据
+        requestPool.offer(request);
+    }
+}

+ 23 - 0
incubator-core/src/main/java/com/incubator/core/pool/WSResponsePool.java

@@ -0,0 +1,23 @@
+package com.incubator.core.pool;
+
+import com.incubator.core.net.ws.WSResponse;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public final class WSResponsePool {
+
+    private static final ConcurrentLinkedQueue<WSResponse> responsePool = new ConcurrentLinkedQueue<>();
+
+    public static WSResponse getResponse() {
+        WSResponse response = responsePool.poll();
+        if (response == null) {
+            response = new WSResponse();
+        }
+        return response;
+    }
+
+    public static void recycle(WSResponse response) {
+        response.reset(); // 清空状态
+        responsePool.offer(response);
+    }
+}

+ 24 - 5
incubator-game/src/main/java/com/incubator/game/listener/PublicListener.java

@@ -3,6 +3,8 @@ package com.incubator.game.listener;
 import com.incubator.core.net.ws.NetHandler;
 import com.incubator.core.net.ws.WSRequest;
 import com.incubator.core.net.ws.WSResponse;
+import com.incubator.core.pool.WSRequestPool;
+import com.incubator.core.pool.WSResponsePool;
 import com.incubator.game.GGame;
 import com.incubator.common.net.Connection;
 import com.incubator.game.player.GPlayer;
@@ -56,11 +58,24 @@ public class PublicListener extends GameServerConnectionListener {
 		if (msg instanceof ByteBuf) {
 			ByteBuf byteBuf = (ByteBuf) msg;
 
+			byte[] bytes = null;
+			WSRequest request = null;
+			WSResponse response = null;
+
             try {
-                byte[] bytes = new byte[byteBuf.readableBytes()];
-                byteBuf.readBytes(bytes);
-				// 提取请求数据
-                WSRequest request = new WSRequest(bytes);
+				// 减少对象分配,通过 ByteBuf 的内置方法获取直接内存访问
+				int readableBytes = byteBuf.readableBytes();
+				if (readableBytes > 0) {
+					bytes = new byte[readableBytes];
+					byteBuf.getBytes(byteBuf.readerIndex(), bytes); // 避免修改 ByteBuf 的读取指针
+				} else {
+					logger.error("收到空消息,断开连接");
+					conn.close();
+					return;
+				}
+
+				// 使用对象池或预先初始化的对象避免频繁创建
+				request = WSRequestPool.getRequest(bytes); // 从对象池获取 WSRequest 实例
 				// 获取处理器
                 NetHandler handler = GGame.handlers.get(request.getCmd());
                 if (handler == null) {
@@ -68,14 +83,18 @@ public class PublicListener extends GameServerConnectionListener {
 					conn.close();
 					return;
                 }
+
 				// 心跳消息特殊处理
 				if (request.getCmd() == CommonProto.Cmd.HeartBeatReq_VALUE) {
 					this.processHeartbeat(conn);
 					return;
 				}
+
+				// 使用池化的 WSResponse 实例,避免频繁创建
+				response = WSResponsePool.getResponse();
+
 				// 处理非心跳消息
 				logger.info("收到消息 : cmd={}, 请求内容 : {}", request.getCmd(), request.toJson());
-				WSResponse response = new WSResponse();
 				handler.onDate(conn, request, response);
 				conn.writeAndFlush(response.toBytes());
 				logger.info("返回消息 : cmd={}, 返回内容 : {}", request.getCmd(), response.toJson());