From 8670fea807ae1b08bd56ba3cc202a7c9f31d8b2c Mon Sep 17 00:00:00 2001 From: godotg Date: Sun, 11 Dec 2022 17:04:07 +0800 Subject: [PATCH] perf[net]: Wrong configuration gives appropriate hints --- .../java/com/zfoo/net/router/IRouter.java | 10 +-- .../main/java/com/zfoo/net/router/Router.java | 18 +----- .../zfoo/net/router/answer/IAsyncAnswer.java | 6 +- .../zfoo/net/router/answer/ISyncAnswer.java | 6 +- .../zfoo/net/router/answer/SyncAnswer.java | 2 +- .../net/router/attachment/AttachmentType.java | 12 ++-- .../router/attachment/GatewayAttachment.java | 22 +++---- .../net/router/attachment/HttpAttachment.java | 2 +- .../net/router/attachment/IAttachment.java | 5 +- .../router/attachment/NoAnswerAttachment.java | 7 +-- .../router/attachment/SignalAttachment.java | 17 ++--- .../net/router/attachment/UdpAttachment.java | 2 +- .../exception/ErrorResponseException.java | 2 +- .../router/exception/NetTimeOutException.java | 2 +- .../UnexpectedProtocolException.java | 2 +- .../net/router/receiver/EnhanceUtils.java | 34 ++++------ .../net/router/receiver/IPacketReceiver.java | 2 +- .../net/router/receiver/PacketReceiver.java | 2 +- .../receiver/PacketReceiverDefinition.java | 13 ++-- .../com/zfoo/net/router/route/PacketBus.java | 63 ++++++++----------- .../zfoo/net/router/route/SignalBridge.java | 15 ++--- 21 files changed, 106 insertions(+), 138 deletions(-) diff --git a/net/src/main/java/com/zfoo/net/router/IRouter.java b/net/src/main/java/com/zfoo/net/router/IRouter.java index 54b05873..9678bd09 100644 --- a/net/src/main/java/com/zfoo/net/router/IRouter.java +++ b/net/src/main/java/com/zfoo/net/router/IRouter.java @@ -20,18 +20,18 @@ import com.zfoo.net.session.model.Session; import com.zfoo.protocol.IPacket; import org.springframework.lang.Nullable; - /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public interface IRouter { + /** + * EN:send() and receive() are the entry points for sending and receiving messages, which can be called directly + * CN:send()和receive()是消息的发送和接收的入口,可以直接调用 + */ void send(Session session, IPacket packet); - /** - * send()和receive()是消息的发送和接收的入口,可以直接调用,是最轻量级发送和接收方式 - */ void send(Session session, IPacket packet, @Nullable IAttachment attachment); void receive(Session session, IPacket packet, @Nullable IAttachment attachment); diff --git a/net/src/main/java/com/zfoo/net/router/Router.java b/net/src/main/java/com/zfoo/net/router/Router.java index e1035a87..62d76285 100644 --- a/net/src/main/java/com/zfoo/net/router/Router.java +++ b/net/src/main/java/com/zfoo/net/router/Router.java @@ -51,9 +51,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** - * 消息派发 + * Message distribution * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class Router implements IRouter { @@ -69,13 +69,8 @@ public class Router implements IRouter { */ private final FastThreadLocal serverReceiveSignalAttachmentThreadLocal = new FastThreadLocal<>(); - /** * 在服务端收到数据后,会调用这个方法. 这个方法在BaseRouteHandler.java的channelRead中被调用 - * - * @param session - * @param packet - * @param attachment */ @Override public void receive(Session session, IPacket packet, @Nullable IAttachment attachment) { @@ -234,13 +229,6 @@ public class Router implements IRouter { * 注意: * 1.这个里面其实还是调用send发送的消息 * 2.这个argument的参数,只用于provider处哪个线程执行,其实就是hashId,如:工会业务,则传入guildId,回调回来后,一定会在发起者线程。 - * - * @param session - * @param packet - * @param answerClass - * @param argument - * @param - * @return */ @Override public AsyncAnswer asyncAsk(Session session, IPacket packet, @Nullable Class answerClass, @Nullable Object argument) { @@ -344,7 +332,7 @@ public class Router implements IRouter { // 调用PacketReceiver,进行真正的业务处理,这个submit只是根据packet找到protocolId,然后进行反射调用 // 这个在哪个线程处理取决于:这个上层的PacketReceiverTask被丢到了哪个线程中 - PacketBus.submit(session, packet, attachment); + PacketBus.route(session, packet, attachment); } catch (Exception e) { EventBus.submit(ServerExceptionEvent.valueOf(session, packet, attachment, e)); logger.error(StringUtils.format("e[uid:{}][sid:{}]未知exception异常", session.getAttribute(AttributeType.UID), session.getSid(), e.getMessage()), e); diff --git a/net/src/main/java/com/zfoo/net/router/answer/IAsyncAnswer.java b/net/src/main/java/com/zfoo/net/router/answer/IAsyncAnswer.java index 22ccc830..545edbe1 100644 --- a/net/src/main/java/com/zfoo/net/router/answer/IAsyncAnswer.java +++ b/net/src/main/java/com/zfoo/net/router/answer/IAsyncAnswer.java @@ -27,12 +27,14 @@ public interface IAsyncAnswer { IAsyncAnswer thenAccept(Consumer consumer); /** - * 接收到异步返回的消息,并处理这个消息,异步请求必须要调用这个方法 + * EN:To receive the message returned asynchronously and process the message, the asynchronous request must call this method + * CN:接收到异步返回的消息,并处理这个消息,异步请求必须要调用这个方法 */ void whenComplete(Consumer consumer); /** - * 没有执行成功的回调的方法 + * EN:If the asynchronous request does not return successfully, the method is called + * CN:如果异步请求没有成功返回,那么就会回调该方法 */ IAsyncAnswer notComplete(SafeRunnable notCompleteCallback); diff --git a/net/src/main/java/com/zfoo/net/router/answer/ISyncAnswer.java b/net/src/main/java/com/zfoo/net/router/answer/ISyncAnswer.java index 9ca909d8..02a74e6f 100644 --- a/net/src/main/java/com/zfoo/net/router/answer/ISyncAnswer.java +++ b/net/src/main/java/com/zfoo/net/router/answer/ISyncAnswer.java @@ -17,18 +17,18 @@ import com.zfoo.net.router.attachment.SignalAttachment; import com.zfoo.protocol.IPacket; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public interface ISyncAnswer { /** - * @return 请求的返回包 + * The return packet for the synchronization request */ T packet(); /** - * @return 同步和异步控制的附加包 + * attachment for synchronous and asynchronous request */ SignalAttachment attachment(); diff --git a/net/src/main/java/com/zfoo/net/router/answer/SyncAnswer.java b/net/src/main/java/com/zfoo/net/router/answer/SyncAnswer.java index 434c2a29..603df0ec 100644 --- a/net/src/main/java/com/zfoo/net/router/answer/SyncAnswer.java +++ b/net/src/main/java/com/zfoo/net/router/answer/SyncAnswer.java @@ -17,7 +17,7 @@ import com.zfoo.net.router.attachment.SignalAttachment; import com.zfoo.protocol.IPacket; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class SyncAnswer implements ISyncAnswer { diff --git a/net/src/main/java/com/zfoo/net/router/attachment/AttachmentType.java b/net/src/main/java/com/zfoo/net/router/attachment/AttachmentType.java index f045675c..a5cacd24 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/AttachmentType.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/AttachmentType.java @@ -16,34 +16,34 @@ import java.util.HashMap; import java.util.Map; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public enum AttachmentType { /** - * 带有同步或者异步信息的附加包 + * synchronous or asynchronous attachment */ SIGNAL_PACKET((byte) 0, SignalAttachment.class), /** - * 带有网关信息的附加包 + * gateway attachment */ GATEWAY_PACKET((byte) 1, GatewayAttachment.class), /** - * udp消息的附加包 + * udp attachment */ UDP_PACKET((byte) 2, UdpAttachment.class), /** - * http消息的附加包 + * http attachment */ HTTP_PACKET((byte) 3, HttpAttachment.class), /** - * 无返回消息的附加包 + * not used attachment */ NO_ANSWER_PACKET((byte) 4, NoAnswerAttachment.class), diff --git a/net/src/main/java/com/zfoo/net/router/attachment/GatewayAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/GatewayAttachment.java index 699f9e72..152beaf3 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/GatewayAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/GatewayAttachment.java @@ -18,9 +18,7 @@ import com.zfoo.util.math.HashUtils; import org.springframework.lang.Nullable; /** - * 附加包对业务层透明,禁止在业务层使用 - * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class GatewayAttachment implements IAttachment { @@ -28,32 +26,34 @@ public class GatewayAttachment implements IAttachment { public static final transient short PROTOCOL_ID = 1; /** - * session的id,一般是客户端连接网关的那个sid + * session id */ private long sid; /** - * 用戶Id,从网关转发到后面的消息必须要附带用户的Id信息,要不然无法知道是哪个用户发过来的,0代表没有用户id + * EN:User ID, the message forwarded from the gateway to the back must be accompanied by the user's ID information, + * otherwise it is impossible to know which user sent it, 0 means no user ID + *

+ * CN:用戶Id,从网关转发到后面的消息必须要附带用户的Id信息,要不然无法知道是哪个用户发过来的,0代表没有用户id */ private long uid; /** - * 是否使用consistentHashId作为一致性hashId + * EN:Whether to use a consistent hash ID as a consistent hash ID + * CN:是否使用consistentHashId作为一致性hashId */ private boolean useExecutorConsistentHash; - /** - * 用来在TaskBus中计算一致性hash的参数 - */ private int executorConsistentHash; /** - * true为客户端,false为服务端 + * true for the client, false for the server */ private boolean client; /** - * 客户端发到网关的可能是一个带有同步或者异步的附加包,网关转发的时候需要把这个附加包给带上 + * EN:The client may send an packet with synchronous or asynchronous to the gateway, and the gateway needs to bring this attachment when forwarding + * CN:客户端发到网关的可能是一个带有同步或者异步的附加包,网关转发的时候需要把这个附加包给带上 */ private SignalAttachment signalAttachment; diff --git a/net/src/main/java/com/zfoo/net/router/attachment/HttpAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/HttpAttachment.java index 59c026a6..132e79b4 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/HttpAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/HttpAttachment.java @@ -17,7 +17,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class HttpAttachment implements IAttachment { diff --git a/net/src/main/java/com/zfoo/net/router/attachment/IAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/IAttachment.java index 0cb56e29..677c55ff 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/IAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/IAttachment.java @@ -15,7 +15,7 @@ package com.zfoo.net.router.attachment; import com.zfoo.protocol.IPacket; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public interface IAttachment extends IPacket { @@ -23,7 +23,8 @@ public interface IAttachment extends IPacket { AttachmentType packetType(); /** - * 用来确定这条消息在哪一个线程处理 + * EN:Used to determine which thread the message is processed on + * CN:用来确定这条消息在哪一个线程处理 * * @return 一致性hashId */ diff --git a/net/src/main/java/com/zfoo/net/router/attachment/NoAnswerAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/NoAnswerAttachment.java index 458e2d63..3cdd140f 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/NoAnswerAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/NoAnswerAttachment.java @@ -13,18 +13,15 @@ package com.zfoo.net.router.attachment; /** - * 附加包对业务层透明,禁止在业务层使用 + * not used attachment * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class NoAnswerAttachment implements IAttachment { public static final transient short PROTOCOL_ID = 4; - /** - * 用来在TaskBus中计算一致性hash的参数 - */ private int executorConsistentHash; public static NoAnswerAttachment valueOf(int executorConsistentHash) { diff --git a/net/src/main/java/com/zfoo/net/router/attachment/SignalAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/SignalAttachment.java index 2e02cf9d..95eddc89 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/SignalAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/SignalAttachment.java @@ -19,9 +19,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; /** - * 附加包对业务层透明,禁止在业务层使用 - * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class SignalAttachment implements IAttachment { @@ -31,27 +29,30 @@ public class SignalAttachment implements IAttachment { public static final AtomicInteger ATOMIC_ID = new AtomicInteger(0); /** - * 唯一标识一个packet, 唯一表示一个Attachment,hashcode() and equals() 也通过signalId计算 + * EN:Unique identification of a packet, unique representation of an attachment, hashcode() and equals() equals signalId value + * CN:唯一标识一个packet, 唯一表示一个Attachment,hashcode() and equals() 等于signalId */ private int signalId = ATOMIC_ID.incrementAndGet(); /** - * 用来在TaskBus中计算一致性hash的参数 + * EN:The parameter used to calculate the consistency hash in Task Bus + * CN:用来在TaskBus中计算一致性hash的参数 */ private int executorConsistentHash = -1; /** - * true为客户端,false为服务端 + * true for the client, false for the server */ private boolean client = true; /** - * 客户端发送的时间 + * The time the client sent it */ private transient long timestamp = TimeUtils.now(); /** - * 客户端收到服务器回复的时候回调的方法 + * EN:The method of callback when the client receives a reply from the server + * CN:客户端收到服务器回复的时候回调的方法 */ private transient CompletableFuture responseFuture = new CompletableFuture<>(); diff --git a/net/src/main/java/com/zfoo/net/router/attachment/UdpAttachment.java b/net/src/main/java/com/zfoo/net/router/attachment/UdpAttachment.java index c3a2d123..f60da67e 100644 --- a/net/src/main/java/com/zfoo/net/router/attachment/UdpAttachment.java +++ b/net/src/main/java/com/zfoo/net/router/attachment/UdpAttachment.java @@ -15,7 +15,7 @@ package com.zfoo.net.router.attachment; import com.zfoo.util.math.RandomUtils; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class UdpAttachment implements IAttachment { diff --git a/net/src/main/java/com/zfoo/net/router/exception/ErrorResponseException.java b/net/src/main/java/com/zfoo/net/router/exception/ErrorResponseException.java index 14ed4512..97db9188 100644 --- a/net/src/main/java/com/zfoo/net/router/exception/ErrorResponseException.java +++ b/net/src/main/java/com/zfoo/net/router/exception/ErrorResponseException.java @@ -16,7 +16,7 @@ package com.zfoo.net.router.exception; import com.zfoo.net.packet.common.Error; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class ErrorResponseException extends RuntimeException { diff --git a/net/src/main/java/com/zfoo/net/router/exception/NetTimeOutException.java b/net/src/main/java/com/zfoo/net/router/exception/NetTimeOutException.java index bf9abac8..5975aa1e 100644 --- a/net/src/main/java/com/zfoo/net/router/exception/NetTimeOutException.java +++ b/net/src/main/java/com/zfoo/net/router/exception/NetTimeOutException.java @@ -14,7 +14,7 @@ package com.zfoo.net.router.exception; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class NetTimeOutException extends RuntimeException { diff --git a/net/src/main/java/com/zfoo/net/router/exception/UnexpectedProtocolException.java b/net/src/main/java/com/zfoo/net/router/exception/UnexpectedProtocolException.java index cf99ed31..47b2cfd7 100644 --- a/net/src/main/java/com/zfoo/net/router/exception/UnexpectedProtocolException.java +++ b/net/src/main/java/com/zfoo/net/router/exception/UnexpectedProtocolException.java @@ -16,7 +16,7 @@ package com.zfoo.net.router.exception; import com.zfoo.protocol.exception.RunException; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class UnexpectedProtocolException extends RunException { diff --git a/net/src/main/java/com/zfoo/net/router/receiver/EnhanceUtils.java b/net/src/main/java/com/zfoo/net/router/receiver/EnhanceUtils.java index 5c65f6bb..54968ea8 100644 --- a/net/src/main/java/com/zfoo/net/router/receiver/EnhanceUtils.java +++ b/net/src/main/java/com/zfoo/net/router/receiver/EnhanceUtils.java @@ -20,13 +20,11 @@ import com.zfoo.protocol.util.StringUtils; import com.zfoo.util.security.IdUtils; import javassist.*; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public abstract class EnhanceUtils { @@ -51,32 +49,27 @@ public abstract class EnhanceUtils { public static IPacketReceiver createPacketReceiver(PacketReceiverDefinition definition) throws NotFoundException, CannotCompileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { var classPool = ClassPool.getDefault(); + var bean = definition.getBean(); + var method = definition.getMethod(); + var packetClazz = definition.getPacketClazz(); + var attachmentClazz = definition.getAttachmentClazz(); - Object bean = definition.getBean(); - Method method = definition.getMethod(); - Class packetClazz = definition.getPacketClazz(); - Class attachmentClazz = definition.getAttachmentClazz(); - - // 定义类名称 - CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getCanonicalName() + "Dispatcher" + IdUtils.getLocalIntId()); + var enhanceClazz = classPool.makeClass(EnhanceUtils.class.getCanonicalName() + "Dispatcher" + IdUtils.getLocalIntId()); enhanceClazz.addInterface(classPool.get(IPacketReceiver.class.getCanonicalName())); - // 定义类中的一个成员 - CtField field = new CtField(classPool.get(bean.getClass().getCanonicalName()), "bean", enhanceClazz); + var field = new CtField(classPool.get(bean.getClass().getCanonicalName()), "bean", enhanceClazz); field.setModifiers(Modifier.PRIVATE); enhanceClazz.addField(field); - // 定义类的构造器 - CtConstructor constructor = new CtConstructor(classPool.get(new String[]{bean.getClass().getCanonicalName()}), enhanceClazz); + var constructor = new CtConstructor(classPool.get(new String[]{bean.getClass().getCanonicalName()}), enhanceClazz); constructor.setBody("{this.bean=$1;}"); constructor.setModifiers(Modifier.PUBLIC); enhanceClazz.addConstructor(constructor); - // 定义类实现的接口方法 - CtMethod invokeMethod = new CtMethod(classPool.get(void.class.getCanonicalName()), "invoke", classPool.get(new String[]{Session.class.getCanonicalName(), IPacket.class.getCanonicalName(), IAttachment.class.getCanonicalName()}), enhanceClazz); + var invokeMethod = new CtMethod(classPool.get(void.class.getCanonicalName()), "invoke", classPool.get(new String[]{Session.class.getCanonicalName(), IPacket.class.getCanonicalName(), IAttachment.class.getCanonicalName()}), enhanceClazz); invokeMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); if (attachmentClazz == null) { - // 强制类型转换 + // Cast type(强制类型转换) String invokeMethodBody = StringUtils.format("{this.bean.{}($1, ({})$2);}", method.getName(), packetClazz.getCanonicalName()); invokeMethod.setBody(invokeMethodBody); } else { @@ -85,12 +78,11 @@ public abstract class EnhanceUtils { } enhanceClazz.addMethod(invokeMethod); - // 释放缓存 enhanceClazz.detach(); - Class resultClazz = enhanceClazz.toClass(IPacketReceiver.class); - Constructor resultConstructor = resultClazz.getConstructor(bean.getClass()); - IPacketReceiver receiver = (IPacketReceiver) resultConstructor.newInstance(bean); + var resultClazz = enhanceClazz.toClass(IPacketReceiver.class); + var resultConstructor = resultClazz.getConstructor(bean.getClass()); + var receiver = (IPacketReceiver) resultConstructor.newInstance(bean); return receiver; } } diff --git a/net/src/main/java/com/zfoo/net/router/receiver/IPacketReceiver.java b/net/src/main/java/com/zfoo/net/router/receiver/IPacketReceiver.java index 80384d6b..86e253df 100644 --- a/net/src/main/java/com/zfoo/net/router/receiver/IPacketReceiver.java +++ b/net/src/main/java/com/zfoo/net/router/receiver/IPacketReceiver.java @@ -18,7 +18,7 @@ import com.zfoo.net.session.model.Session; import com.zfoo.protocol.IPacket; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ public interface IPacketReceiver { diff --git a/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiver.java b/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiver.java index 99002e9f..bacbf4e1 100644 --- a/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiver.java +++ b/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiver.java @@ -16,7 +16,7 @@ package com.zfoo.net.router.receiver; import java.lang.annotation.*; /** - * @author jaysunxiao + * @author godotg * @version 3.0 */ @Documented diff --git a/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiverDefinition.java b/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiverDefinition.java index cc12c2a5..9c37c710 100644 --- a/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiverDefinition.java +++ b/net/src/main/java/com/zfoo/net/router/receiver/PacketReceiverDefinition.java @@ -21,30 +21,31 @@ import com.zfoo.protocol.util.ReflectionUtils; import java.lang.reflect.Method; /** - * 动态代理被PacketReceiver注解标注的方法,为了避免反射最终会用javassist字节码增强的方法去代理PacketReceiverDefinition + * EN:Dynamic proxy methods annotated by PacketReceiver annotations, to avoid reflection, will eventually use javassist bytecode enhanced methods to proxy this class + * CN:动态代理被PacketReceiver注解标注的方法,为了避免反射最终会用javassist字节码增强的方法去代理PacketReceiverDefinition * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class PacketReceiverDefinition implements IPacketReceiver { /** - * 一个controller的bean + * A controller bean */ private Object bean; /** - * 被PacketReceiver注解标注的方法,接受的方法public void atTcpHelloRequest(Session session, TcpHelloRequest request) + * Methods annotated by PacketReceiver annotations, eg: public void atTcpHelloRequest(Session session, TcpHelloRequest request) */ private Method method; /** - * 接收的包的Class类,如TcpHelloRequest + * The protocol class that receives the package, eg: TcpHelloRequest */ private Class packetClazz; /** - * 接收的包的附加包的Class类,如GatewayAttachment + * attachment class, eg: GatewayAttachment */ private Class attachmentClazz; diff --git a/net/src/main/java/com/zfoo/net/router/route/PacketBus.java b/net/src/main/java/com/zfoo/net/router/route/PacketBus.java index e04276cf..f56f0e5c 100644 --- a/net/src/main/java/com/zfoo/net/router/route/PacketBus.java +++ b/net/src/main/java/com/zfoo/net/router/route/PacketBus.java @@ -37,9 +37,10 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Modifier; /** - * 包的接收路线,服务器收到packet调用对应的Receiver + * EN:The receiving route of the packet, the server/client receives the packet and then call corresponding to the Receiver + * CN:包的接收路线,服务器收到packet然后调用对应的Receiver * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public abstract class PacketBus { @@ -47,19 +48,13 @@ public abstract class PacketBus { private static final Logger logger = LoggerFactory.getLogger(PacketBus.class); /** - * 正常消息的接收 - *

- * 发送者同时能发送多个包 - * 接收者同时只能处理一个session的一个包,同一个发送者发送过来的包排队处理 + * The routing of the message */ - public static void submit(Session session, IPacket packet, IAttachment attachment) { - // 客户端和服务端都有接受packet的方法,packetReceiverList对应的就是包的接收方法,将receiver注册到IProtocolRegistration + public static void route(Session session, IPacket packet, IAttachment attachment) { var packetReceiver = (IPacketReceiver) ProtocolManager.getProtocol(packet.protocolId()).receiver(); if (packetReceiver == null) { throw new RuntimeException(StringUtils.format("no any packetReceiverDefinition found for this [packet:{}]", packet.getClass().getName())); } - - // 调用PacketReceiver packetReceiver.invoke(session, packet, attachment); } @@ -73,58 +68,52 @@ public abstract class PacketBus { } if (!ReflectionUtils.isPojoClass(clazz)) { - logger.warn("消息注册类[{}]不是POJO类,父类的消息接收不会被扫描到", clazz); + logger.warn("The message registration class [{}] is not a POJO class, and the parent class will not be scanned", clazz); } for (var method : methods) { var paramClazzs = method.getParameterTypes(); - AssertionUtils.isTrue(paramClazzs.length == 2 || paramClazzs.length == 3 - , "[class:{}] [method:{}] must have two or three parameter!", bean.getClass().getName(), method.getName()); + AssertionUtils.isTrue(paramClazzs.length == 2 || paramClazzs.length == 3, "[class:{}] [method:{}] must have two or three parameter!", bean.getClass().getName(), method.getName()); - AssertionUtils.isTrue(Session.class.isAssignableFrom(paramClazzs[0]) - , "[class:{}] [method:{}],the first parameter must be Session type parameter Exception.", bean.getClass().getName(), method.getName()); + AssertionUtils.isTrue(Session.class.isAssignableFrom(paramClazzs[0]), "[class:{}] [method:{}],the first parameter must be Session type parameter Exception.", bean.getClass().getName(), method.getName()); - AssertionUtils.isTrue(IPacket.class.isAssignableFrom(paramClazzs[1]) - , "[class:{}] [method:{}],the second parameter must be IPacket type parameter Exception.", bean.getClass().getName(), method.getName()); + AssertionUtils.isTrue(IPacket.class.isAssignableFrom(paramClazzs[1]), "[class:{}] [method:{}],the second parameter must be IPacket type parameter Exception.", bean.getClass().getName(), method.getName()); - AssertionUtils.isTrue(paramClazzs.length != 3 || IAttachment.class.isAssignableFrom(paramClazzs[2]) - , "[class:{}] [method:{}],the third parameter must be IAttachment type parameter Exception.", bean.getClass().getName(), method.getName()); + AssertionUtils.isTrue(paramClazzs.length != 3 || IAttachment.class.isAssignableFrom(paramClazzs[2]), "[class:{}] [method:{}],the third parameter must be IAttachment type parameter Exception.", bean.getClass().getName(), method.getName()); var packetClazz = (Class) paramClazzs[1]; var attachmentClazz = paramClazzs.length == 3 ? paramClazzs[2] : null; var packetName = packetClazz.getCanonicalName(); var methodName = method.getName(); - AssertionUtils.isTrue(Modifier.isPublic(method.getModifiers()) - , "[class:{}] [method:{}] [packet:{}] must use 'public' as modifier!", bean.getClass().getName(), methodName, packetName); + AssertionUtils.isTrue(Modifier.isPublic(method.getModifiers()), "[class:{}] [method:{}] [packet:{}] must use 'public' as modifier!", bean.getClass().getName(), methodName, packetName); - AssertionUtils.isTrue(!Modifier.isStatic(method.getModifiers()) - , "[class:{}] [method:{}] [packet:{}] can not use 'static' as modifier!", bean.getClass().getName(), methodName, packetName); + AssertionUtils.isTrue(!Modifier.isStatic(method.getModifiers()), "[class:{}] [method:{}] [packet:{}] can not use 'static' as modifier!", bean.getClass().getName(), methodName, packetName); var expectedMethodName = StringUtils.format("at{}", packetClazz.getSimpleName()); - AssertionUtils.isTrue(methodName.equals(expectedMethodName) - , "[class:{}] [method:{}] [packet:{}] expects '{}' as method name!", bean.getClass().getName(), methodName, packetName, expectedMethodName); + AssertionUtils.isTrue(methodName.equals(expectedMethodName), "[class:{}] [method:{}] [packet:{}] expects '{}' as method name!", bean.getClass().getName(), methodName, packetName, expectedMethodName); - // 如果以Request结尾的请求,那么attachment应该为GatewayAttachment - // 如果以Ask结尾的请求,那么attachment不能为GatewayAttachment + // If the request class name ends with Request, then the attachment should be a Gateway Attachment + // If the request class name ends with Ask, then attachment cannot be a Gateway Attachment if (attachmentClazz != null) { if (packetName.endsWith(PacketService.NET_REQUEST_SUFFIX)) { - AssertionUtils.isTrue(attachmentClazz.equals(GatewayAttachment.class) || attachmentClazz.equals(UdpAttachment.class) || attachmentClazz.equals(HttpAttachment.class) - , "[class:{}] [method:{}] [packet:{}] must use [attachment:{}]!", bean.getClass().getName(), methodName, packetName, GatewayAttachment.class.getCanonicalName()); + AssertionUtils.isTrue(attachmentClazz.equals(GatewayAttachment.class) || attachmentClazz.equals(UdpAttachment.class) || attachmentClazz.equals(HttpAttachment.class), "[class:{}] [method:{}] [packet:{}] must use [attachment:{}]!", bean.getClass().getName(), methodName, packetName, GatewayAttachment.class.getCanonicalName()); } else if (packetName.endsWith(PacketService.NET_ASK_SUFFIX)) { - AssertionUtils.isTrue(!attachmentClazz.equals(GatewayAttachment.class) - , "[class:{}] [method:{}] [packet:{}] can not match with [attachment:{}]!", bean.getClass().getName(), methodName, packetName, GatewayAttachment.class.getCanonicalName()); + AssertionUtils.isTrue(!attachmentClazz.equals(GatewayAttachment.class), "[class:{}] [method:{}] [packet:{}] can not match with [attachment:{}]!", bean.getClass().getName(), methodName, packetName, GatewayAttachment.class.getCanonicalName()); } } + var protocolId = Short.MIN_VALUE; + try { + protocolId = ProtocolManager.protocolId(packetClazz); + } catch (Exception e) { + throw new RunException("[class:{}][protocolId:{}] has no registration, please register for this protocol", packetClazz.getSimpleName(), protocolId); + } + try { - var protocolId = ProtocolManager.protocolId(packetClazz); - // 将receiver注册到IProtocolRegistration var protocolRegistration = ProtocolManager.getProtocol(protocolId); - AssertionUtils.notNull(protocolRegistration, "协议类[class:{}][protocolId:{}]没有注册", packetClazz.getSimpleName(), protocolId); - AssertionUtils.isNull(protocolRegistration.receiver(), "协议类[class:{}]被重复接收[at{}],一个协议只能对应一个被@PacketReceiver标注的方法" - , packetClazz.getSimpleName(), packetClazz.getSimpleName()); + AssertionUtils.isNull(protocolRegistration.receiver(), "duplicate protocol registration, @PacketReceiver [class:{}] is repeatedly received [at{}]", packetClazz.getSimpleName(), packetClazz.getSimpleName()); var receiverDefinition = new PacketReceiverDefinition(bean, method, packetClazz, attachmentClazz); var enhanceReceiverDefinition = EnhanceUtils.createPacketReceiver(receiverDefinition); @@ -133,7 +122,7 @@ public abstract class PacketBus { ReflectionUtils.makeAccessible(receiverField); ReflectionUtils.setField(receiverField, protocolRegistration, enhanceReceiverDefinition); } catch (Throwable t) { - throw new RunException(t, "解析协议类[class:{}]未知异常", packetClazz.getSimpleName()); + throw new RunException(t, "Registration protocol [class:{}] unknown exception", packetClazz.getSimpleName()); } } } diff --git a/net/src/main/java/com/zfoo/net/router/route/SignalBridge.java b/net/src/main/java/com/zfoo/net/router/route/SignalBridge.java index f03d3341..adf392d9 100644 --- a/net/src/main/java/com/zfoo/net/router/route/SignalBridge.java +++ b/net/src/main/java/com/zfoo/net/router/route/SignalBridge.java @@ -22,9 +22,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReferenceArray; /** - * 同步或异步的调用控制器,同步和异步调用的信号沟通桥梁 + * EN:Synchronous or asynchronous call controller, synchronous and asynchronous call signal communication bridge + * CN:同步或异步的调用控制器,同步和异步调用的信号沟通桥梁 * - * @author jaysunxiao + * @author godotg * @version 3.0 */ public class SignalBridge { @@ -35,20 +36,16 @@ public class SignalBridge { private static final int SIGNAL_MASK = 0B00000000_00000000_01111111_11111111; /** - * 用来保存同步或异步请求的SignalAttachment附加包,signalId和SIGNAL_MASK取与的结果hash作为数组索引,使用AtomicReferenceArray只是为了提升性能 - */ - private static final AtomicReferenceArray signalAttachmentArray = new AtomicReferenceArray<>(SIGNAL_MASK + 1); - - /** - * 用来保存同步或异步请求的SignalAttachment附加包,key:signalId + * key:signalId */ private static final Map signalAttachmentMap = new ConcurrentHashMap<>(1000); + private static final AtomicReferenceArray signalAttachmentArray = new AtomicReferenceArray<>(SIGNAL_MASK + 1); public static void addSignalAttachment(SignalAttachment signalAttachment) { var signalId = signalAttachment.getSignalId(); var hash = signalId & SIGNAL_MASK; - // 使用AtomicReferenceArray只是为了提升性能,仅使用ConcurrentHashMap依然可以运行 + // Using an Atomic Reference Array is just to improve performance, and only using a ConcurrentHashMap will still work if (signalAttachmentArray.compareAndSet(hash, null, signalAttachment)) { return; }