From 5746449cfb2bbf85f3ec5ba4399adde41a7e9da0 Mon Sep 17 00:00:00 2001 From: redkale Date: Wed, 5 Apr 2023 22:52:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96sncp=E7=89=88WebSocketNode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/redkale/boot/NodeServer.java | 2 +- .../java/org/redkale/boot/NodeSncpServer.java | 8 +-- src/main/java/org/redkale/net/sncp/Sncp.java | 52 ++++++++------- .../org/redkale/net/sncp/SncpRemoteInfo.java | 19 +++--- .../org/redkale/net/sncp/SncpServlet.java | 66 ++++++++++--------- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/main/java/org/redkale/boot/NodeServer.java b/src/main/java/org/redkale/boot/NodeServer.java index 29bb6843b..27990858e 100644 --- a/src/main/java/org/redkale/boot/NodeServer.java +++ b/src/main/java/org/redkale/boot/NodeServer.java @@ -464,7 +464,7 @@ public abstract class NodeServer { } final ResourceTypeLoader resourceLoader = (ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) -> { try { - if (Sncp.loadMethodActions(serviceImplClass).isEmpty() + if (Sncp.loadMethodActions(Sncp.getResourceType(serviceImplClass)).isEmpty() && (serviceImplClass.getAnnotation(Priority.class) == null && serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的, 通常为BaseService if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) { logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method"); diff --git a/src/main/java/org/redkale/boot/NodeSncpServer.java b/src/main/java/org/redkale/boot/NodeSncpServer.java index e8ef371c4..0ccf5d07c 100644 --- a/src/main/java/org/redkale/boot/NodeSncpServer.java +++ b/src/main/java/org/redkale/boot/NodeSncpServer.java @@ -78,8 +78,8 @@ public class NodeSncpServer extends NodeServer { int maxTypeLength = 0; int maxNameLength = 0; for (SncpServlet en : servlets) { - maxNameLength = Math.max(maxNameLength, en.getServiceName().length() + 1); - maxTypeLength = Math.max(maxTypeLength, en.getServiceType().getName().length()); + maxNameLength = Math.max(maxNameLength, en.getResourceName().length() + 1); + maxTypeLength = Math.max(maxTypeLength, en.getResourceType().getName().length()); } for (SncpServlet en : servlets) { if (sb != null) { @@ -93,8 +93,8 @@ public class NodeSncpServer extends NodeServer { private StringBuilder toSimpleString(SncpServlet servlet, int maxTypeLength, int maxNameLength) { StringBuilder sb = new StringBuilder(); - Class serviceType = servlet.getServiceType(); - String serviceName = servlet.getServiceName(); + Class serviceType = servlet.getResourceType(); + String serviceName = servlet.getResourceName(); int size = servlet.getActionSize(); sb.append(SncpServlet.class.getSimpleName()).append(" (type=").append(serviceType.getName()); int len = maxTypeLength - serviceType.getName().length(); diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index d907a3b75..b8b047e50 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -62,7 +62,7 @@ public abstract class Sncp { boolean remote(); - Class type(); //resourceServiceType + Class type(); //serviceType int index() default 0; //排列顺序, 主要用于Method } @@ -83,6 +83,7 @@ public abstract class Sncp { final List list = new ArrayList<>(); final List multis = new ArrayList<>(); final Map actionids = new LinkedHashMap<>(); + RedkaleClassLoader.putReflectionPublicMethods(resourceServiceType.getName()); for (final java.lang.reflect.Method method : resourceServiceType.getMethods()) { if (method.isSynthetic()) { continue; @@ -237,10 +238,16 @@ public abstract class Sncp { ResourceType type = serviceImplClass.getAnnotation(ResourceType.class); return type != null ? type.value() : serviceImplClass; } -// -// public static Class getServiceType(Service service) { -// return isSncpDyn(service) && service.getClass().getSimpleName().startsWith("_Dyn") ? service.getClass().getSuperclass() : service.getClass(); -// } + + public static Class getServiceType(Service service) { + SncpDyn dyn = service.getClass().getAnnotation(SncpDyn.class); + return dyn != null ? dyn.type() : service.getClass(); + } + + public static Class getServiceType(Class serviceImplClass) { + SncpDyn dyn = serviceImplClass.getAnnotation(SncpDyn.class); + return dyn != null ? dyn.type() : serviceImplClass; + } public static AnyValue getResourceConf(Service service) { if (service == null || !isSncpDyn(service)) { @@ -456,7 +463,7 @@ public abstract class Sncp { { av0 = cw.visitAnnotation(sncpDynDesc, true); av0.visit("remote", Boolean.FALSE); - av0.visit("type", Type.getType(Type.getDescriptor(getResourceType(serviceImplClass)))); + av0.visit("type", Type.getType(Type.getDescriptor(serviceImplClass))); av0.visitEnd(); } { //给新类加上原有的Annotation @@ -663,18 +670,27 @@ public abstract class Sncp { if (!java.lang.reflect.Modifier.isPublic(mod)) { return null; } - final SncpRemoteInfo info = createSncpRemoteInfo(name, serviceTypeOrImplClass, serviceTypeOrImplClass, BsonConvert.root(), sncpRpcGroups, client, agent, remoteGroup); + final SncpRemoteInfo info = createSncpRemoteInfo(name, getResourceType(serviceTypeOrImplClass), serviceTypeOrImplClass, BsonConvert.root(), sncpRpcGroups, client, agent, remoteGroup); final String supDynName = serviceTypeOrImplClass.getName().replace('.', '/'); - final String clientName = SncpClient.class.getName().replace('.', '/'); final String sncpInfoName = SncpRemoteInfo.class.getName().replace('.', '/'); final String resDesc = Type.getDescriptor(Resource.class); final String sncpInfoDesc = Type.getDescriptor(SncpRemoteInfo.class); - final String clientDesc = Type.getDescriptor(SncpClient.class); final String sncpDynDesc = Type.getDescriptor(SncpDyn.class); final String anyValueDesc = Type.getDescriptor(AnyValue.class); final ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader; - //final String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName(); - final String newDynName = "org/redkaledyn/service/remote/_DynRemoteService__" + serviceTypeOrImplClass.getName().replace('.', '_').replace('$', '_'); + String newDynName = "org/redkaledyn/service/remote/_DynRemoteService__" + serviceTypeOrImplClass.getName().replace('.', '_').replace('$', '_'); + if (!name.isEmpty()) { + boolean normal = true; + for (char ch : name.toCharArray()) { + if (!((ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) { + normal = false; + } + } + if (!normal) { + throw new SncpException(serviceTypeOrImplClass + "'s resource name is illegal, must be 0-9 _ a-z A-Z"); + } + newDynName += "_" + (normal ? name : hash(name)); + } try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz; @@ -774,15 +790,7 @@ public abstract class Sncp { // mv.visitMaxs(1, 1); // mv.visitEnd(); // } - int i = -1; - Uint128 serviceid = serviceid(name, serviceTypeOrImplClass); - final List serviceActions = new ArrayList<>(); - Class serviceImpClass = realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass; - for (Map.Entry en : loadMethodActions(serviceImpClass).entrySet()) { - serviceActions.add(new SncpRemoteAction(serviceImpClass, en.getValue(), serviceid, en.getKey())); - } - for (final SncpRemoteAction entry : serviceActions) { - final int index = ++i; + for (final SncpRemoteAction entry : info.getActions()) { final java.lang.reflect.Method method = entry.method; { mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null)); @@ -798,7 +806,7 @@ public abstract class Sncp { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_sncp", sncpInfoDesc); - MethodDebugVisitor.pushInt(mv, index); + mv.visitLdcInsn(entry.actionid.toString()); { //传参数 int paramlen = entry.paramTypes.length; @@ -830,7 +838,7 @@ public abstract class Sncp { } } - mv.visitMethodInsn(INVOKEVIRTUAL, sncpInfoName, "remote", "(I[Ljava/lang/Object;)Ljava/lang/Object;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, sncpInfoName, "remote", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", false); //mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); if (method.getGenericReturnType() == void.class) { mv.visitInsn(POP); diff --git a/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java b/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java index fa47c5c45..2a044e353 100644 --- a/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java +++ b/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java @@ -44,7 +44,8 @@ public class SncpRemoteInfo { protected final int serviceVersion; - protected final SncpRemoteAction[] actions; + //key: actionid.Uint128.toString() + protected final Map actions = new HashMap<>(); //非MQ模式下此字段才有值 protected final SncpRpcGroups sncpRpcGroups; @@ -86,16 +87,14 @@ public class SncpRemoteInfo { this.messageClient = messageAgent == null ? null : messageAgent.getSncpMessageClient(); this.topic = messageAgent == null ? null : messageAgent.generateSncpReqTopic(resourceName, resourceType); - final List serviceActions = new ArrayList<>(); - for (Map.Entry en : loadMethodActions(resourceType).entrySet()) { - serviceActions.add(new SncpRemoteAction(serviceImplClass, en.getValue(), serviceid, en.getKey())); + for (Map.Entry en : loadMethodActions(Sncp.getServiceType(serviceImplClass)).entrySet()) { + this.actions.put(en.getKey().toString(), new SncpRemoteAction(serviceImplClass, en.getValue(), serviceid, en.getKey())); } - this.actions = serviceActions.toArray(new SncpRemoteAction[serviceActions.size()]); } //由远程模式的DyncRemoveService调用 - public T remote(final int index, final Object... params) { - final SncpRemoteAction action = this.actions[index]; + public T remote(final String actionid, final Object... params) { + final SncpRemoteAction action = this.actions.get(actionid); CompletionHandler callbackHandler = null; Object callbackHandlerAttach = null; if (action.paramHandlerIndex >= 0) { @@ -249,7 +248,7 @@ public class SncpRemoteInfo { return this.getClass().getSimpleName() + "(service = " + serviceType.getSimpleName() + ", serviceid = " + serviceid + ", serviceVersion = " + serviceVersion + ", name = '" + name + "', address = " + (clientSncpAddress == null ? "" : (clientSncpAddress.getHostString() + ":" + clientSncpAddress.getPort())) - + ", actions.size = " + actions.length + ")"; + + ", actions.size = " + actions.size() + ")"; } public String toSimpleString() { //给Sncp产生的Service用 @@ -257,7 +256,7 @@ public class SncpRemoteInfo { return serviceType.getSimpleName() + "(name = '" + name + "', serviceid = " + serviceid + ", serviceVersion = " + serviceVersion + ", clientaddr = " + (clientSncpAddress == null ? "" : (clientSncpAddress.getHostString() + ":" + clientSncpAddress.getPort())) + ((remoteGroup == null || remoteGroup.isEmpty()) ? "" : ", remoteGroup = " + remoteGroup) - + ", actions.size = " + actions.length + ")"; + + ", actions.size = " + actions.size() + ")"; } public void updateRemoteAddress(String remoteGroup, Set remoteAddresses) { @@ -282,7 +281,7 @@ public class SncpRemoteInfo { } public SncpRemoteAction[] getActions() { - return actions; + return actions.values().toArray(new SncpRemoteAction[actions.size()]); } public String getTopic() { diff --git a/src/main/java/org/redkale/net/sncp/SncpServlet.java b/src/main/java/org/redkale/net/sncp/SncpServlet.java index d245080ef..9ee7200c9 100644 --- a/src/main/java/org/redkale/net/sncp/SncpServlet.java +++ b/src/main/java/org/redkale/net/sncp/SncpServlet.java @@ -31,9 +31,9 @@ import org.redkale.util.*; */ public class SncpServlet extends Servlet implements Comparable { - protected final Class serviceType; + protected final Class resourceType; - protected final String serviceName; + protected final String resourceName; protected final Service service; @@ -42,24 +42,25 @@ public class SncpServlet extends Servlet private final HashMap actions = new HashMap<>(); private SncpServlet(String resourceName, Class resourceType, Service service, Uint128 serviceid) { - this.serviceName = resourceName; - this.serviceType = resourceType; + this.resourceName = resourceName; + this.resourceType = resourceType; this.service = service; this.serviceid = serviceid; } protected SncpServlet(String resourceName, Class resourceType, Service service) { - this.serviceName = resourceName; - this.serviceType = resourceType; + this.resourceName = resourceName; + this.resourceType = resourceType; this.service = service; this._nonBlocking = true; this.serviceid = Sncp.serviceid(resourceName, resourceType); - RedkaleClassLoader.putReflectionPublicMethods(service.getClass().getName()); - for (Map.Entry en : Sncp.loadMethodActions(resourceType).entrySet()) { + Class serviceImplClass = Sncp.getServiceType(service); + RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); + for (Map.Entry en : Sncp.loadMethodActions(serviceImplClass).entrySet()) { SncpActionServlet action; try { - action = SncpActionServlet.create(resourceName, resourceType, service, serviceid, en.getKey(), en.getValue()); + action = SncpActionServlet.create(resourceName, resourceType, serviceImplClass, service, serviceid, en.getKey(), en.getValue()); } catch (RuntimeException e) { throw new SncpException(en.getValue() + " create " + SncpActionServlet.class.getSimpleName() + " error", e); } @@ -103,8 +104,8 @@ public class SncpServlet extends Servlet @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()).append(" (type=").append(serviceType.getName()); - sb.append(", serviceid=").append(serviceid).append(", name='").append(serviceName).append("'"); + sb.append(this.getClass().getSimpleName()).append(" (type=").append(resourceType.getName()); + sb.append(", serviceid=").append(serviceid).append(", name='").append(resourceName).append("'"); sb.append(", actions.size=").append(actions.size() > 9 ? "" : " ").append(actions.size()).append(")"); return sb.toString(); } @@ -113,12 +114,12 @@ public class SncpServlet extends Servlet return service; } - public String getServiceName() { - return serviceName; + public String getResourceName() { + return resourceName; } - public Class getServiceType() { - return serviceType; + public Class getResourceType() { + return resourceType; } public Uint128 getServiceid() { @@ -136,20 +137,20 @@ public class SncpServlet extends Servlet } SncpServlet o = other; int rs = 0; - if (this.serviceType == null) { - rs = o.serviceType == null ? 0 : -1; - } else if (o.serviceType == null) { + if (this.resourceType == null) { + rs = o.resourceType == null ? 0 : -1; + } else if (o.resourceType == null) { rs = 1; } else { - rs = this.serviceType.getName().compareTo(o.serviceType.getName()); + rs = this.resourceType.getName().compareTo(o.resourceType.getName()); } if (rs == 0) { - if (this.serviceName == null) { - rs = o.serviceName == null ? 0 : -1; - } else if (o.serviceName == null) { + if (this.resourceName == null) { + rs = o.resourceName == null ? 0 : -1; + } else if (o.resourceName == null) { rs = 1; } else { - rs = this.serviceName.compareTo(o.serviceName); + rs = this.resourceName.compareTo(o.resourceName); } } return rs; @@ -424,12 +425,13 @@ public class SncpServlet extends Servlet * * * - * @param resourceName 资源名 - * @param resourceType 资源类 - * @param service Service - * @param serviceid 类ID - * @param actionid 操作ID - * @param method 方法 + * @param resourceName 资源名 + * @param resourceType 资源类 + * @param serviceImplClass Service实现类 + * @param service Service + * @param serviceid 类ID + * @param actionid 操作ID + * @param method 方法 * * @return SncpActionServlet */ @@ -437,6 +439,7 @@ public class SncpServlet extends Servlet public static SncpActionServlet create( final String resourceName, final Class resourceType, + final Class serviceImplClass, final Service service, final Uint128 serviceid, final Uint128 actionid, @@ -445,6 +448,7 @@ public class SncpServlet extends Servlet final Class serviceClass = service.getClass(); final String supDynName = SncpActionServlet.class.getName().replace('.', '/'); final String resourceTypeName = resourceType.getName().replace('.', '/'); + final String serviceImpTypeName = serviceImplClass.getName().replace('.', '/'); final String convertName = Convert.class.getName().replace('.', '/'); final String uint128Desc = Type.getDescriptor(Uint128.class); final String convertDesc = Type.getDescriptor(Convert.class); @@ -594,14 +598,14 @@ public class SncpServlet extends Servlet { //调用service mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()Lorg/redkale/service/Service;", false); - mv.visitTypeInsn(CHECKCAST, resourceTypeName); + mv.visitTypeInsn(CHECKCAST, serviceImpTypeName); mv.visitVarInsn(ASTORE, store); mv.visitVarInsn(ALOAD, store); for (int[] j : codes) { mv.visitVarInsn(j[0], j[1]); } - mv.visitMethodInsn(resourceType.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, resourceTypeName, method.getName(), Type.getMethodDescriptor(method), resourceType.isInterface()); + mv.visitMethodInsn(resourceType.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, serviceImpTypeName, method.getName(), Type.getMethodDescriptor(method), resourceType.isInterface()); store++; } if (method.getReturnType() != void.class) {