diff --git a/src/main/java/org/redkale/boot/NodeSncpServer.java b/src/main/java/org/redkale/boot/NodeSncpServer.java index 8950aa05e..a4f625b0d 100644 --- a/src/main/java/org/redkale/boot/NodeSncpServer.java +++ b/src/main/java/org/redkale/boot/NodeSncpServer.java @@ -126,7 +126,7 @@ public class NodeSncpServer extends NodeServer { @Override protected void loadServlet(ClassFilter servletFilter, ClassFilter otherFilter) throws Exception { RedkaleClassLoader.putReflectionPublicClasses(SncpServlet.class.getName()); - RedkaleClassLoader.putReflectionPublicClasses(OldSncpDynServlet.class.getName()); + RedkaleClassLoader.putReflectionPublicClasses(SncpDynServlet.class.getName()); } @Override diff --git a/src/main/java/org/redkale/convert/Convert.java b/src/main/java/org/redkale/convert/Convert.java index 942eb06bc..7c2db9c00 100644 --- a/src/main/java/org/redkale/convert/Convert.java +++ b/src/main/java/org/redkale/convert/Convert.java @@ -57,6 +57,8 @@ public abstract class Convert { public abstract T convertFrom(final Type type, final byte[] bytes); + public abstract T convertFrom(final Type type, final R reader); + //@since 2.2.0 public abstract T convertFrom(final Type type, final byte[] bytes, final int offset, final int length); diff --git a/src/main/java/org/redkale/convert/bson/BsonConvert.java b/src/main/java/org/redkale/convert/bson/BsonConvert.java index 2e0a31235..1fca652c3 100644 --- a/src/main/java/org/redkale/convert/bson/BsonConvert.java +++ b/src/main/java/org/redkale/convert/bson/BsonConvert.java @@ -164,6 +164,7 @@ public class BsonConvert extends BinaryConvert { return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(mask, buffers)); } + @Override @SuppressWarnings("unchecked") public T convertFrom(final Type type, final BsonReader reader) { if (type == null) { diff --git a/src/main/java/org/redkale/convert/json/JsonConvert.java b/src/main/java/org/redkale/convert/json/JsonConvert.java index c396defc2..bd0b3bf3f 100644 --- a/src/main/java/org/redkale/convert/json/JsonConvert.java +++ b/src/main/java/org/redkale/convert/json/JsonConvert.java @@ -182,6 +182,7 @@ public class JsonConvert extends TextConvert { return (T) decoder.convertFrom(new JsonByteBufferReader(mask, buffers)); } + @Override public T convertFrom(final Type type, final JsonReader reader) { if (type == null) { return null; diff --git a/src/main/java/org/redkale/net/sncp/OldSncpClient.java b/src/main/java/org/redkale/net/sncp/OldSncpClient.java index 5bc8fee3f..0aca53579 100644 --- a/src/main/java/org/redkale/net/sncp/OldSncpClient.java +++ b/src/main/java/org/redkale/net/sncp/OldSncpClient.java @@ -329,9 +329,10 @@ public final class OldSncpClient { return; } checkResult(seqid, action, buffer); - - final int respBodyLength = buffer.getInt(); + buffer.getInt(); // abilities + buffer.getLong(); // timestamp final int retcode = buffer.getInt(); + final int respBodyLength = buffer.getInt(); if (retcode != 0) { logger.log(Level.SEVERE, action.method + " sncp (params: " + convert.convertTo(params) + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + "), params=" + JsonConvert.root().convertTo(params)); throw new SncpException("remote service(" + action.method + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + ")"); diff --git a/src/main/java/org/redkale/net/sncp/OldSncpDynServlet.java b/src/main/java/org/redkale/net/sncp/OldSncpDynServlet.java deleted file mode 100644 index 8e138a3a4..000000000 --- a/src/main/java/org/redkale/net/sncp/OldSncpDynServlet.java +++ /dev/null @@ -1,727 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.net.sncp; - -import java.io.IOException; -import java.lang.reflect.*; -import java.nio.channels.CompletionHandler; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.*; -import org.redkale.annotation.*; -import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES; -import org.redkale.asm.*; -import static org.redkale.asm.Opcodes.*; -import org.redkale.asm.Type; -import org.redkale.convert.bson.*; -import org.redkale.net.sncp.OldSncpHandler.DefaultSncpAsyncHandler; -import static org.redkale.net.sncp.SncpHeader.HEADER_SIZE; -import org.redkale.service.Service; -import org.redkale.util.*; - -/** - *
-         *  public class TestService implements Service {
-         *
-         *      public boolean change(TestBean bean, String name, int id) {
-         *          return false;
-         *      }
-         *
-         *      public void insert(CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
-         *      }
-         *
-         *      public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
-         *      }
-         *
-         *      public CompletableFuture<String> changeName(TestBean bean, String name, int id) {
-         *          return null;
-         *      }
-         * }
-         *
-         *
-         * class DynActionTestService_change extends SncpServletAction {
-         *
-         *      public TestService service;
-         *
-         *      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          TestBean arg1 = convert.convertFrom(paramTypes[1], in);
-          String arg2 = convert.convertFrom(paramTypes[2], in);
-          int arg3 = convert.convertFrom(paramTypes[3], in);
-          Object rs = service.change(arg1, arg2, arg3);
-          _callParameter(out, arg1, arg2, arg3);
-          convert.convertTo(out, paramTypes[0], rs);
-      }
- }
-
- class DynActionTestService_insert extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          OldSncpHandler arg0 = handler;
-          convert.convertFrom(CompletionHandler.class, in);
-          TestBean arg1 = convert.convertFrom(paramTypes[2], in);
-          String arg2 = convert.convertFrom(paramTypes[3], in);
-          int arg3 = convert.convertFrom(paramTypes[4], in);
-          handler.sncp_setParams(arg0, arg1, arg2, arg3);
-          service.insert(arg0, arg1, arg2, arg3);
-       }
- }
-
- class DynActionTestService_update extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          long a1 = convert.convertFrom(paramTypes[1], in);
-          short a2 = convert.convertFrom(paramTypes[2], in);
-          OldSncpHandler a3 = handler;
-          convert.convertFrom(CompletionHandler.class, in);
-          TestBean arg1 = convert.convertFrom(paramTypes[4], in);
-          String arg2 = convert.convertFrom(paramTypes[5], in);
-          int arg3 = convert.convertFrom(paramTypes[6], in);
-          handler.sncp_setParams(a1, a2, a3, arg1, arg2, arg3);
-          service.update(a1, a2, a3, arg1, arg2, arg3);
-      }
- }
-
-
- class DynActionTestService_changeName extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(final BsonReader in, final BsonWriter out, final OldSncpHandler handler) throws Throwable {
-          TestBean arg1 = convert.convertFrom(paramTypes[1], in);
-          String arg2 = convert.convertFrom(paramTypes[2], in);
-          int arg3 = convert.convertFrom(paramTypes[3], in);
-          handler.sncp_setParams(arg1, arg2, arg3);
-          CompletableFuture future = service.changeName(arg1, arg2, arg3);
-          handler.sncp_setFuture(future);
-      }
- }
-
- 
- */ -public final class OldSncpDynServlet extends SncpServlet { - - private final AtomicInteger maxTypeLength; - - private final AtomicInteger maxNameLength; - - private static final Logger logger = Logger.getLogger(OldSncpDynServlet.class.getSimpleName()); - - private final Uint128 serviceid; - - private final HashMap actions = new HashMap<>(); - - public OldSncpDynServlet(final BsonConvert convert, final String serviceResourceName, final Class serviceResourceType, final Service service, - final AtomicInteger maxTypeLength, AtomicInteger maxNameLength) { - super(serviceResourceName, serviceResourceType, service); - this.maxTypeLength = maxTypeLength; - this.maxNameLength = maxNameLength; - this.serviceid = Sncp.serviceid(serviceResourceName, serviceResourceType); - RedkaleClassLoader.putReflectionPublicMethods(service.getClass().getName()); - for (Map.Entry en : Sncp.loadMethodActions(serviceResourceType).entrySet()) { - SncpServletAction action; - try { - action = SncpServletAction.create(service, serviceid, en.getKey(), en.getValue()); - } catch (RuntimeException e) { - throw new SncpException(en.getValue() + " create " + SncpServletAction.class.getSimpleName() + " error", e); - } - action.convert = convert; - actions.put(en.getKey(), action); - } - maxNameLength.set(Math.max(maxNameLength.get(), serviceResourceName.length() + 1)); - maxTypeLength.set(Math.max(maxTypeLength.get(), serviceType.getName().length())); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()).append(" (type=").append(serviceType.getName()); - int len = this.maxTypeLength.get() - serviceType.getName().length(); - for (int i = 0; i < len; i++) { - sb.append(' '); - } - sb.append(", serviceid=").append(serviceid).append(", name='").append(serviceName).append("'"); - for (int i = 0; i < this.maxNameLength.get() - serviceName.length(); i++) { - sb.append(' '); - } - sb.append(", actions.size=").append(actions.size() > 9 ? "" : " ").append(actions.size()).append(")"); - return sb.toString(); - } - - @Override - public Uint128 getServiceid() { - return serviceid; - } - - @Override - public int compareTo(SncpServlet other) { - if (!(other instanceof OldSncpDynServlet)) { - return 1; - } - OldSncpDynServlet o = (OldSncpDynServlet) other; - int rs = this.serviceType.getName().compareTo(o.serviceType.getName()); - if (rs == 0) { - rs = this.serviceName.compareTo(o.serviceName); - } - return rs; - } - - @Override - @SuppressWarnings("unchecked") - public void execute(SncpRequest request, SncpResponse response) throws IOException { - final SncpServletAction action = actions.get(request.getHeader().getActionid()); - //logger.log(Level.FINEST, "sncpdyn.execute: " + request + ", " + (action == null ? "null" : action.method)); - if (action == null) { - response.finish(SncpResponse.RETCODE_ILLACTIONID, null); //无效actionid - } else { - BsonWriter out = action.convert.pollBsonWriter(); - out.writePlaceholderTo(HEADER_SIZE); - BsonReader in = action.convert.pollBsonReader(); - OldSncpHandler handler = null; - try { - if (action.handlerFuncParamIndex >= 0) { - if (action.handlerFuncParamType == CompletionHandler.class) { - handler = new DefaultSncpAsyncHandler(logger, action, in, out, request, response); - } else { - Creator creator = action.handlerCreator; - if (creator == null) { - creator = OldSncpHandler.Factory.createCreator(action.handlerFuncParamType); - action.handlerCreator = creator; - } - handler = creator.create(new DefaultSncpAsyncHandler(logger, action, in, out, request, response)); - } - } else if (action.boolReturnTypeFuture) { - handler = new DefaultSncpAsyncHandler(logger, action, in, out, request, response); - } - in.setBytes(request.getBody()); - action.action(in, out, handler); - if (handler == null) { - response.finish(0, out); - action.convert.offerBsonReader(in); - action.convert.offerBsonWriter(out); - } else if (action.boolReturnTypeFuture) { - CompletableFuture future = handler.sncp_getFuture(); - if (future == null) { - action._callParameter(out, handler.sncp_getParams()); - action.convert.convertTo(out, Object.class, null); - } else { - Object[] sncpParams = handler.sncp_getParams(); - future.whenComplete((v, e) -> { - if (e != null) { - response.getContext().getLogger().log(Level.SEVERE, "sncp CompleteAsync error(" + request + ")", e); - response.finish(SncpResponse.RETCODE_THROWEXCEPTION, null); - return; - } - action._callParameter(out, sncpParams); - action.convert.convertTo(out, Object.class, v); - response.finish(0, out); - action.convert.offerBsonReader(in); - action.convert.offerBsonWriter(out); - }); - } - } - } catch (Throwable t) { - response.getContext().getLogger().log(Level.SEVERE, "sncp execute error(" + request + ")", t); - response.finish(SncpResponse.RETCODE_THROWEXCEPTION, null); - } - } - } - - public static abstract class SncpServletAction { - - public Method method; - - public Creator handlerCreator; - - protected boolean nonBlocking; - - @Resource - protected BsonConvert convert; - - protected org.redkale.util.Attribute[] paramAttrs; // 为null表示无RpcCall处理,index=0固定为null, 其他为参数标记的RpcCall回调方法 - - protected java.lang.reflect.Type[] paramTypes; //index=0表示返回参数的type, void的返回参数类型为null - - protected int handlerFuncParamIndex = -1; //handlerFuncParamIndex>=0表示存在CompletionHandler参数 - - protected Class handlerFuncParamType; //CompletionHandler参数的类型 - - protected boolean boolReturnTypeFuture = false; // 返回结果类型是否为 CompletableFuture - - public abstract void action(final BsonReader in, final BsonWriter out, final OldSncpHandler handler) throws Throwable; - - //只有同步方法才调用 (没有CompletionHandler、CompletableFuture) - public final void _callParameter(final BsonWriter out, final Object... params) { - if (paramAttrs != null) { - for (int i = 1; i < paramAttrs.length; i++) { - org.redkale.util.Attribute attr = paramAttrs[i]; - if (attr == null) { - continue; - } - out.writeByte((byte) i); - convert.convertTo(out, attr.genericType(), attr.get(params[i - 1])); - } - } - out.writeByte((byte) 0); - } - - public String actionName() { - return method.getDeclaringClass().getSimpleName() + "." + method.getName(); - } - - /** - *
-         *  public class TestService implements Service {
-         *
-         *      public boolean change(TestBean bean, String name, int id) {
-         *          return false;
-         *      }
-         *
-         *      public void insert(CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
-         *      }
-         *
-         *      public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
-         *      }
-         *
-         *      public CompletableFuture<String> changeName(TestBean bean, String name, int id) {
-         *          return null;
-         *      }
-         * }
-         *
-         *
-         * class DynActionTestService_change extends SncpServletAction {
-         *
-         *      public TestService service;
-         *
-         *      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          TestBean arg1 = convert.convertFrom(paramTypes[1], in);
-          String arg2 = convert.convertFrom(paramTypes[2], in);
-          int arg3 = convert.convertFrom(paramTypes[3], in);
-          Object rs = service.change(arg1, arg2, arg3);
-          _callParameter(out, arg1, arg2, arg3);
-          convert.convertTo(out, paramTypes[0], rs);
-      }
- }
-
- class DynActionTestService_insert extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          OldSncpHandler arg0 = handler;
-          convert.convertFrom(CompletionHandler.class, in);
-          TestBean arg1 = convert.convertFrom(paramTypes[2], in);
-          String arg2 = convert.convertFrom(paramTypes[3], in);
-          int arg3 = convert.convertFrom(paramTypes[4], in);
-          handler.sncp_setParams(arg0, arg1, arg2, arg3);
-          service.insert(arg0, arg1, arg2, arg3);
-       }
- }
-
- class DynActionTestService_update extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(BsonReader in, BsonWriter out, OldSncpHandler handler) throws Throwable {
-          long a1 = convert.convertFrom(paramTypes[1], in);
-          short a2 = convert.convertFrom(paramTypes[2], in);
-          OldSncpHandler a3 = handler;
-          convert.convertFrom(CompletionHandler.class, in);
-          TestBean arg1 = convert.convertFrom(paramTypes[4], in);
-          String arg2 = convert.convertFrom(paramTypes[5], in);
-          int arg3 = convert.convertFrom(paramTypes[6], in);
-          handler.sncp_setParams(a1, a2, a3, arg1, arg2, arg3);
-          service.update(a1, a2, a3, arg1, arg2, arg3);
-      }
- }
-
-
- class DynActionTestService_changeName extends SncpServletAction {
-
-      public TestService service;
-
-      @Override
-      public void action(final BsonReader in, final BsonWriter out, final OldSncpHandler handler) throws Throwable {
-          TestBean arg1 = convert.convertFrom(paramTypes[1], in);
-          String arg2 = convert.convertFrom(paramTypes[2], in);
-          int arg3 = convert.convertFrom(paramTypes[3], in);
-          handler.sncp_setParams(arg1, arg2, arg3);
-          CompletableFuture future = service.changeName(arg1, arg2, arg3);
-          handler.sncp_setFuture(future);
-      }
- }
-
- 
- * - * @param service Service - * @param serviceid 类ID - * @param actionid 操作ID - * @param method 方法 - * - * @return SncpServletAction - */ - @SuppressWarnings("unchecked") - public static SncpServletAction create(final Service service, final Uint128 serviceid, final Uint128 actionid, final Method method) { - final Class serviceClass = service.getClass(); - final String supDynName = SncpServletAction.class.getName().replace('.', '/'); - final String serviceName = serviceClass.getName().replace('.', '/'); - final String convertName = BsonConvert.class.getName().replace('.', '/'); - final String handlerName = OldSncpHandler.class.getName().replace('.', '/'); - final String asyncHandlerDesc = Type.getDescriptor(OldSncpHandler.class); - final String convertReaderDesc = Type.getDescriptor(BsonReader.class); - final String convertWriterDesc = Type.getDescriptor(BsonWriter.class); - final String serviceDesc = Type.getDescriptor(serviceClass); - final boolean boolReturnTypeFuture = CompletableFuture.class.isAssignableFrom(method.getReturnType()); - final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__" + serviceClass.getName().replace('.', '_').replace('$', '_') + "__" + method.getName() + "__" + actionid; - - int handlerFuncIndex = -1; - Class handlerFuncType = null; - Class newClazz = null; - try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - newClazz = clz == null ? Thread.currentThread().getContextClassLoader().loadClass(newDynName.replace('/', '.')) : clz; - final Class[] paramClasses = method.getParameterTypes(); - for (int i = 0; i < paramClasses.length; i++) { //反序列化方法的每个参数 - if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) { - handlerFuncIndex = i; - handlerFuncType = paramClasses[i]; - break; - } - } - } catch (Throwable ex) { - } - - final java.lang.reflect.Type[] originalParamTypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceClass); - final java.lang.reflect.Type originalReturnType = TypeToken.getGenericType(method.getGenericReturnType(), serviceClass); - if (newClazz == null) { - //------------------------------------------------------------- - ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); - FieldVisitor fv; - MethodDebugVisitor mv; - - cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); - { - { - fv = cw.visitField(ACC_PUBLIC, "service", serviceDesc, null, null); - fv.visitEnd(); - } - fv.visitEnd(); - } - { // constructor方法 - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, supDynName, "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - String convertFromDesc = "(Ljava/lang/reflect/Type;" + convertReaderDesc + ")Ljava/lang/Object;"; - try { - convertFromDesc = Type.getMethodDescriptor(BsonConvert.class.getMethod("convertFrom", java.lang.reflect.Type.class, BsonReader.class)); - } catch (Exception ex) { - throw new SncpException(ex); //不可能会发生 - } - { // action方法 - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "action", "(" + convertReaderDesc + convertWriterDesc + asyncHandlerDesc + ")V", null, new String[]{"java/lang/Throwable"})); - //mv.setDebug(true); - int iconst = ICONST_1; - int intconst = 1; - int store = 4; //action的参数个数+1 - final Class[] paramClasses = method.getParameterTypes(); - int[][] codes = new int[paramClasses.length][2]; - for (int i = 0; i < paramClasses.length; i++) { //反序列化方法的每个参数 - if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) { - if (boolReturnTypeFuture) { - throw new SncpException(method + " have both CompletionHandler and CompletableFuture"); - } - if (handlerFuncIndex >= 0) { - throw new SncpException(method + " have more than one CompletionHandler type parameter"); - } - Sncp.checkAsyncModifier(paramClasses[i], method); - handlerFuncIndex = i; - handlerFuncType = paramClasses[i]; - mv.visitVarInsn(ALOAD, 3); - mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/')); - mv.visitVarInsn(ASTORE, store); - codes[i] = new int[]{ALOAD, store}; - store++; - iconst++; - intconst++; - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class)); - mv.visitLdcInsn(Type.getType(Type.getDescriptor(CompletionHandler.class))); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); - mv.visitInsn(POP); - continue; - } - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;"); - - if (intconst < 6) { - mv.visitInsn(ICONST_0 + intconst); - } else if (iconst <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, intconst); - } else if (iconst <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, intconst); - } else { - mv.visitLdcInsn(intconst); - } - mv.visitInsn(AALOAD); - mv.visitVarInsn(ALOAD, 1); - - mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); - int load = ALOAD; - int v = 0; - if (paramClasses[i].isPrimitive()) { - int storecode = ISTORE; - load = ILOAD; - if (paramClasses[i] == long.class) { - storecode = LSTORE; - load = LLOAD; - v = 1; - } else if (paramClasses[i] == float.class) { - storecode = FSTORE; - load = FLOAD; - v = 1; - } else if (paramClasses[i] == double.class) { - storecode = DSTORE; - load = DLOAD; - v = 1; - } - Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]); - String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/'); - try { - Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value"); - mv.visitTypeInsn(CHECKCAST, bigPrimitiveName); - mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false); - } catch (Exception ex) { - throw new SncpException(ex); //不可能会发生 - } - mv.visitVarInsn(storecode, store); - } else { - mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/')); - mv.visitVarInsn(ASTORE, store); // - } - codes[i] = new int[]{load, store}; - store += v; - iconst++; - intconst++; - store++; - } - if (boolReturnTypeFuture || handlerFuncIndex >= 0) { //调用SncpAsyncHandler.setParams(Object... params) - mv.visitVarInsn(ALOAD, 3); - if (paramClasses.length < 6) { - mv.visitInsn(ICONST_0 + paramClasses.length); - } else if (paramClasses.length <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, paramClasses.length); - } else if (paramClasses.length <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, paramClasses.length); - } else { - mv.visitLdcInsn(paramClasses.length); - } - - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - int insn = 3; //action的参数个数 - for (int j = 0; j < paramClasses.length; j++) { - final Class pt = paramClasses[j]; - mv.visitInsn(DUP); - insn++; - if (j < 6) { - mv.visitInsn(ICONST_0 + j); - } else if (j <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, j); - } else if (j <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, j); - } else { - mv.visitLdcInsn(j); - } - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = TypeToken.primitiveToWrapper(pt); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - mv.visitMethodInsn(INVOKEINTERFACE, handlerName, "sncp_setParams", "([Ljava/lang/Object;)V", true); - } - { //调用service - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "service", serviceDesc); - for (int[] j : codes) { - mv.visitVarInsn(j[0], j[1]); - } - mv.visitMethodInsn(INVOKEVIRTUAL, serviceName, method.getName(), Type.getMethodDescriptor(method), false); - } - - final Class returnClass = method.getReturnType(); - if (returnClass != void.class) { - if (returnClass.isPrimitive()) { - Class bigClass = TypeToken.primitiveToWrapper(returnClass); - try { - Method vo = bigClass.getMethod("valueOf", returnClass); - mv.visitMethodInsn(INVOKESTATIC, bigClass.getName().replace('.', '/'), vo.getName(), Type.getMethodDescriptor(vo), false); - } catch (Exception ex) { - throw new SncpException(ex); //不可能会发生 - } - } - mv.visitVarInsn(ASTORE, store); //11 - if (boolReturnTypeFuture) { - mv.visitVarInsn(ALOAD, 3); - mv.visitVarInsn(ALOAD, store); - mv.visitMethodInsn(INVOKEINTERFACE, handlerName, "sncp_setFuture", "(Ljava/util/concurrent/CompletableFuture;)V", true); - } - } - if (!boolReturnTypeFuture && handlerFuncIndex < 0) { //同步方法 - //------------------------- _callParameter 方法 -------------------------------- - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 2); - if (paramClasses.length < 6) { //参数总数量 - mv.visitInsn(ICONST_0 + paramClasses.length); - } else if (paramClasses.length <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, paramClasses.length); - } else if (paramClasses.length <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, paramClasses.length); - } else { - mv.visitLdcInsn(paramClasses.length); - } - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - int insn = 3;//action的参数个数 - for (int j = 0; j < paramClasses.length; j++) { - final Class pt = paramClasses[j]; - mv.visitInsn(DUP); - insn++; - if (j < 6) { - mv.visitInsn(ICONST_0 + j); - } else if (j <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, j); - } else if (j <= Short.MAX_VALUE) { - mv.visitIntInsn(SIPUSH, j); - } else { - mv.visitLdcInsn(j); - } - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = TypeToken.primitiveToWrapper(pt); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "_callParameter", "(" + convertWriterDesc + "[Ljava/lang/Object;)V", false); - } - //-------------------------直接返回 或者 调用convertTo方法 -------------------------------- - int maxStack = codes.length > 0 ? codes[codes.length - 1][1] : 1; - if (boolReturnTypeFuture || returnClass == void.class) { //返回 - mv.visitInsn(RETURN); - maxStack = 8; - } else { //同步方法调用 - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class)); - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;"); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); - mv.visitVarInsn(ALOAD, store); - mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertTo", "(" + convertWriterDesc + "Ljava/lang/reflect/Type;Ljava/lang/Object;)V", false); - mv.visitInsn(RETURN); - store++; - } - mv.visitMaxs(maxStack, store); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - newClazz = new ClassLoader(serviceClass.getClassLoader()) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); - RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); - try { - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), newClazz.getField("service")); - } catch (Exception e) { - } - for (java.lang.reflect.Type t : originalParamTypes) { - if (t.toString().startsWith("java.lang.")) { - continue; - } - BsonFactory.root().loadDecoder(t); - } - if (originalReturnType != void.class && originalReturnType != Void.class) { - if (boolReturnTypeFuture && method.getReturnType() != method.getGenericReturnType()) { - java.lang.reflect.Type t = ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]; - if (t != Void.class && t != java.lang.reflect.Type.class) { - BsonFactory.root().loadEncoder(t); - } - } else { - try { - BsonFactory.root().loadEncoder(originalReturnType); - } catch (Exception e) { - System.err.println(method); - } - } - } - } - NonBlocking non = method.getAnnotation(NonBlocking.class); - if (non == null) { - non = service.getClass().getAnnotation(NonBlocking.class); - } - try { - SncpServletAction instance = (SncpServletAction) newClazz.getDeclaredConstructor().newInstance(); - instance.method = method; - instance.nonBlocking = non == null ? false : non.value(); - java.lang.reflect.Type[] types = new java.lang.reflect.Type[originalParamTypes.length + 1]; - types[0] = originalReturnType; - System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length); - instance.paramTypes = types; - instance.handlerFuncParamIndex = handlerFuncIndex; - instance.handlerFuncParamType = handlerFuncType; - instance.boolReturnTypeFuture = boolReturnTypeFuture; - newClazz.getField("service").set(instance, service); - return instance; - } catch (Exception ex) { - throw new SncpException(ex); //不可能会发生 - } - } - } - -} diff --git a/src/main/java/org/redkale/net/sncp/OldSncpHandler.java b/src/main/java/org/redkale/net/sncp/OldSncpHandler.java deleted file mode 100644 index b0df6e21b..000000000 --- a/src/main/java/org/redkale/net/sncp/OldSncpHandler.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.net.sncp; - -import java.nio.channels.CompletionHandler; -import java.util.concurrent.CompletableFuture; -import java.util.logging.*; -import org.redkale.annotation.ConstructorParameters; -import org.redkale.asm.*; -import static org.redkale.asm.Opcodes.*; -import org.redkale.convert.bson.*; -import org.redkale.net.sncp.OldSncpDynServlet.SncpServletAction; -import org.redkale.util.*; - -/** - * 异步回调函数
- * - * public class _DyncSncpAsyncHandler extends XXXAsyncHandler implements SncpAsyncHandler - * - * - *

- * 详情见: https://redkale.org - * - * @author zhangjx - * @param 结果对象的泛型 - * @param 附件对象的泛型 - */ -public interface OldSncpHandler extends CompletionHandler { - - public Object[] sncp_getParams(); - - public void sncp_setParams(Object... params); - - public void sncp_setFuture(CompletableFuture future); - - public CompletableFuture sncp_getFuture(); - - static class Factory { - - /** - *

-
- 考虑点:
-      1、CompletionHandler子类是接口,且还有其他多个方法
-      2、CompletionHandler子类是类, 需要继承,且必须有空参数构造函数
-      3、CompletionHandler子类无论是接口还是类,都可能存在其他泛型
-
-  public class XXXAsyncHandler_DynSncpAsyncHandler extends XXXAsyncHandler implements OldSncpHandler {
-
-      private OldSncpHandler sncphandler;
-
-      private CompletableFuture sncpfuture;
-
-      @ConstructorParameters({"sncphandler"})
-      public XXXAsyncHandler_DynSncpAsyncHandler(OldSncpHandler sncphandler) {
-          super();
-          this.sncphandler = sncphandler;
-      }
-
-      @Override
-         *      public void completed(Object result, Object attachment) {
-         *          sncphandler.completed(result, attachment);
-         *      }
-         *
-         *      @Override
-         *      public void failed(Throwable exc, Object attachment) {
-         *          sncphandler.failed(exc, attachment);
-         *      }
-         *
-         *      @Override
-         *      public Object[] sncp_getParams() {
-         *          return sncphandler.sncp_getParams();
-         *      }
-         *
-         *      @Override
-         *      public void sncp_setParams(Object... params) {
-         *          sncphandler.sncp_setParams(params);
-         *      }
-         *
-         *      @Override
-         *      public void sncp_setFuture(CompletableFuture future) {
-         *          this.sncpfuture = future;
-         *      }
-         *
-         *      @Override
-         *      public CompletableFuture sncp_getFuture() {
-         *          return this.sncpfuture;
-         *      }
-         *  }
-         *
-         * 
- * - * @param handlerClass CompletionHandler类型或子类 - * - * @return Creator - */ - public static Creator createCreator(Class handlerClass) { - //------------------------------------------------------------- - final boolean handlerinterface = handlerClass.isInterface(); - final String handlerClassName = handlerClass.getName().replace('.', '/'); - final String sncpHandlerName = OldSncpHandler.class.getName().replace('.', '/'); - final String cpDesc = Type.getDescriptor(ConstructorParameters.class); - final String sncpHandlerDesc = Type.getDescriptor(OldSncpHandler.class); - final String sncpFutureDesc = Type.getDescriptor(CompletableFuture.class); - final String newDynName = "org/redkaledyn/sncp/handler/_Dyn" + OldSncpHandler.class.getSimpleName() - + "__" + handlerClass.getName().replace('.', '/').replace('$', '_'); - try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - Class newHandlerClazz = clz == null ? Thread.currentThread().getContextClassLoader().loadClass(newDynName.replace('/', '.')) : clz; - return Creator.create(newHandlerClazz); - } catch (Throwable ex) { - } - // ------------------------------------------------------------------------------ - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - FieldVisitor fv; - MethodDebugVisitor mv; - AnnotationVisitor av0; - cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, handlerinterface ? "java/lang/Object" : handlerClassName, handlerinterface ? new String[]{handlerClassName, sncpHandlerName} : new String[]{sncpHandlerName}); - - { //handler 属性 - fv = cw.visitField(ACC_PRIVATE, "sncphandler", sncpHandlerDesc, null, null); - fv.visitEnd(); - } - { //future 属性 - fv = cw.visitField(ACC_PRIVATE, "sncpfuture", sncpFutureDesc, null, null); - fv.visitEnd(); - } - {//构造方法 - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "", "(" + sncpHandlerDesc + ")V", null, null)); - //mv.setDebug(true); - { - av0 = mv.visitAnnotation(cpDesc, true); - { - AnnotationVisitor av1 = av0.visitArray("value"); - av1.visit(null, "sncphandler"); - av1.visitEnd(); - } - av0.visitEnd(); - } - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, handlerinterface ? "java/lang/Object" : handlerClassName, "", "()V", false); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, newDynName, "sncphandler", sncpHandlerDesc); - mv.visitInsn(RETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - - for (java.lang.reflect.Method method : handlerClass.getMethods()) { // - if ("completed".equals(method.getName()) && method.getParameterCount() == 2) { - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "completed", Type.getMethodDescriptor(method), null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "sncphandler", sncpHandlerDesc); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEINTERFACE, sncpHandlerName, "completed", "(Ljava/lang/Object;Ljava/lang/Object;)V", true); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } else if ("failed".equals(method.getName()) && method.getParameterCount() == 2) { - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "failed", Type.getMethodDescriptor(method), null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "sncphandler", sncpHandlerDesc); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEINTERFACE, sncpHandlerName, "failed", "(Ljava/lang/Throwable;Ljava/lang/Object;)V", true); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } else if (handlerinterface || java.lang.reflect.Modifier.isAbstract(method.getModifiers())) { - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null)); - Class returnType = method.getReturnType(); - if (returnType == void.class) { - mv.visitInsn(RETURN); - mv.visitMaxs(0, 1); - } else if (returnType.isPrimitive()) { - mv.visitInsn(ICONST_0); - if (returnType == long.class) { - mv.visitInsn(LRETURN); - mv.visitMaxs(2, 1); - } else if (returnType == float.class) { - mv.visitInsn(FRETURN); - mv.visitMaxs(2, 1); - } else if (returnType == double.class) { - mv.visitInsn(DRETURN); - mv.visitMaxs(2, 1); - } else { - mv.visitInsn(IRETURN); - mv.visitMaxs(1, 1); - } - } else { - mv.visitInsn(ACONST_NULL); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - } - mv.visitEnd(); - } - } - { // sncp_getParams - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "sncp_getParams", "()[Ljava/lang/Object;", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "sncphandler", sncpHandlerDesc); - mv.visitMethodInsn(INVOKEINTERFACE, sncpHandlerName, "sncp_getParams", "()[Ljava/lang/Object;", true); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { // sncp_setParams - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "sncp_setParams", "([Ljava/lang/Object;)V", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "sncphandler", sncpHandlerDesc); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEINTERFACE, sncpHandlerName, "sncp_setParams", "([Ljava/lang/Object;)V", true); - mv.visitInsn(RETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - { // sncp_setFuture - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "sncp_setFuture", "(" + sncpFutureDesc + ")V", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, newDynName, "sncpfuture", sncpFutureDesc); - mv.visitInsn(RETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - { // sncp_getFuture - mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "sncp_getFuture", "()" + sncpFutureDesc, null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "sncpfuture", sncpFutureDesc); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - cw.visitEnd(); - byte[] bytes = cw.toByteArray(); - Class newClazz = (Class) new ClassLoader(handlerClass.getClassLoader()) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); - return Creator.create(newClazz); - } - - } - - public static class DefaultSncpAsyncHandler implements OldSncpHandler { - - //为了在回调函数中调用_callParameter方法 - protected Object[] params; - - protected SncpServletAction action; - - protected BsonReader in; - - protected BsonWriter out; - - protected SncpRequest request; - - protected SncpResponse response; - - protected CompletableFuture future; - - protected Logger logger; - - public DefaultSncpAsyncHandler(Logger logger, SncpServletAction action, BsonReader in, BsonWriter out, SncpRequest request, SncpResponse response) { - this.logger = logger; - this.action = action; - this.in = in; - this.out = out; - this.request = request; - this.response = response; - } - - @Override - public void completed(Object result, Object attachment) { - try { - action._callParameter(out, sncp_getParams()); - action.convert.convertTo(out, Object.class, result); - response.finish(0, out); - } catch (Exception e) { - failed(e, attachment); - } finally { - action.convert.offerBsonReader(in); - action.convert.offerBsonWriter(out); - } - } - - @Override - public void failed(Throwable exc, Object attachment) { - response.getContext().getLogger().log(Level.INFO, "Sncp execute error(" + request + ")", exc); - response.finish(SncpResponse.RETCODE_THROWEXCEPTION, null); - } - - @Override - public Object[] sncp_getParams() { - return params; - } - - @Override - public void sncp_setParams(Object... params) { - this.params = params; - } - - @Override - public void sncp_setFuture(CompletableFuture future) { - this.future = future; - } - - @Override - public CompletableFuture sncp_getFuture() { - return this.future; - } - - } -} diff --git a/src/main/java/org/redkale/net/sncp/SncpDynServlet.java b/src/main/java/org/redkale/net/sncp/SncpDynServlet.java index c178a730c..692e23606 100644 --- a/src/main/java/org/redkale/net/sncp/SncpDynServlet.java +++ b/src/main/java/org/redkale/net/sncp/SncpDynServlet.java @@ -17,7 +17,8 @@ import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES; import org.redkale.asm.*; import static org.redkale.asm.Opcodes.*; import org.redkale.asm.Type; -import org.redkale.convert.bson.*; +import org.redkale.convert.*; +import org.redkale.convert.bson.BsonFactory; import org.redkale.service.Service; import org.redkale.util.*; @@ -81,10 +82,10 @@ public final class SncpDynServlet extends SncpServlet { @Override public int compareTo(SncpServlet other) { - if (!(other instanceof OldSncpDynServlet)) { + if (!(other instanceof SncpDynServlet)) { return 1; } - OldSncpDynServlet o = (OldSncpDynServlet) other; + SncpDynServlet o = (SncpDynServlet) other; int rs = this.serviceType.getName().compareTo(o.serviceType.getName()); if (rs == 0) { rs = this.serviceName.compareTo(o.serviceName); @@ -347,10 +348,10 @@ public final class SncpDynServlet extends SncpServlet { final Class serviceClass = service.getClass(); final String supDynName = SncpActionServlet.class.getName().replace('.', '/'); final String resourceTypeName = resourceType.getName().replace('.', '/'); - final String convertName = BsonConvert.class.getName().replace('.', '/'); + final String convertName = Convert.class.getName().replace('.', '/'); final String uint128Desc = Type.getDescriptor(Uint128.class); - final String convertDesc = Type.getDescriptor(BsonConvert.class); - final String bsonReaderDesc = Type.getDescriptor(BsonReader.class); + final String convertDesc = Type.getDescriptor(Convert.class); + final String readerDesc = Type.getDescriptor(Reader.class); final String requestName = SncpRequest.class.getName().replace('.', '/'); final String responseName = SncpResponse.class.getName().replace('.', '/'); final String requestDesc = Type.getDescriptor(SncpRequest.class); @@ -388,23 +389,23 @@ public final class SncpDynServlet extends SncpServlet { mv.visitMaxs(7, 7); mv.visitEnd(); } - String convertFromDesc = "(Ljava/lang/reflect/Type;" + bsonReaderDesc + ")Ljava/lang/Object;"; + String convertFromDesc = "(Ljava/lang/reflect/Type;" + readerDesc + ")Ljava/lang/Object;"; try { - convertFromDesc = Type.getMethodDescriptor(BsonConvert.class.getMethod("convertFrom", java.lang.reflect.Type.class, BsonReader.class)); + convertFromDesc = Type.getMethodDescriptor(Convert.class.getMethod("convertFrom", java.lang.reflect.Type.class, Reader.class)); } catch (Exception ex) { throw new SncpException(ex); //不可能会发生 } { // action方法 mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "action", "(" + requestDesc + responseDesc + ")V", null, new String[]{"java/lang/Throwable"})); //mv.setDebug(true); - { //BsonConvert + { //Convert mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getBsonConvert", "()" + convertDesc, false); + mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getConvert", "()" + convertDesc, false); mv.visitVarInsn(ASTORE, 3); } - { //BsonReader + { //Reader mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getBsonReader", "()" + bsonReaderDesc, false); + mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getReader", "()" + readerDesc, false); mv.visitVarInsn(ASTORE, 4); } int iconst = ICONST_1; diff --git a/src/main/java/org/redkale/net/sncp/SncpHeader.java b/src/main/java/org/redkale/net/sncp/SncpHeader.java index 5e589ebdc..ca086957b 100644 --- a/src/main/java/org/redkale/net/sncp/SncpHeader.java +++ b/src/main/java/org/redkale/net/sncp/SncpHeader.java @@ -14,7 +14,7 @@ import org.redkale.util.*; */ public class SncpHeader { - public static final int HEADER_SIZE = 60; + public static final int HEADER_SIZE = 72; private static final byte[] EMPTY_ADDR = new byte[4]; @@ -30,13 +30,20 @@ public class SncpHeader { //SncpRequest的值是clientSncpAddress,SncpResponse的值是serverSncpAddress private byte[] addrBytes; + //响应方地址端口 private int addrPort; - private int bodyLength; + // 预留扩展位 + private int abilities; + //时间戳 + private long timestamp; + + //结果码,非0表示错误 private int retcode; - private long timestamp; //待加入 + 8 + //body长度 + private int bodyLength; private boolean valid; @@ -60,8 +67,10 @@ public class SncpHeader { this.addrBytes = new byte[4]; buffer.get(this.addrBytes); //addr 4 this.addrPort = buffer.getChar(); //port 2 - this.bodyLength = buffer.getInt(); //4 + this.abilities = buffer.getInt(); //4 + this.timestamp = buffer.getLong(); //8 this.retcode = buffer.getInt(); //4 + this.bodyLength = buffer.getInt(); //4 return size; } @@ -78,13 +87,17 @@ public class SncpHeader { offset += 4; this.actionid = array.getUint128(offset); //16 offset += 16; - this.addrBytes = array.getBytes(offset, 4); //addr 4 + this.addrBytes = array.getBytes(offset, 4); //addr 4 offset += 4; this.addrPort = array.getChar(offset); //port 2 offset += 2; - this.bodyLength = array.getInt(offset); //4 + this.abilities = array.getInt(offset); //4 offset += 4; - this.retcode = array.getInt(offset); //4 + this.timestamp = array.getLong(offset); //8 + offset += 4; + this.retcode = array.getInt(offset); //4 + offset += 4; + this.bodyLength = array.getInt(offset); //4 return size; } @@ -110,9 +123,13 @@ public class SncpHeader { offset += 4; array.putChar(offset, (char) newAddrPort); //2 offset += 2; - array.putInt(offset, bodyLength); //4 + array.putInt(offset, abilities); //4 offset += 4; - array.putInt(offset, retcode); //4 + array.putLong(offset, System.currentTimeMillis()); //8 + offset += 8; + array.putInt(offset, retcode); //4 + offset += 4; + array.putInt(offset, bodyLength); //4 return array; } @@ -123,8 +140,9 @@ public class SncpHeader { + ",serviceVersion=" + this.serviceVersion + ",actionid=" + this.actionid + ",address=" + getAddress() - + ",bodyLength=" + this.bodyLength + + ",timestamp=" + this.timestamp + ",retcode=" + this.retcode + + ",bodyLength=" + this.bodyLength + "}"; } diff --git a/src/main/java/org/redkale/net/sncp/SncpRequest.java b/src/main/java/org/redkale/net/sncp/SncpRequest.java index 203f63554..bf3796ce8 100644 --- a/src/main/java/org/redkale/net/sncp/SncpRequest.java +++ b/src/main/java/org/redkale/net/sncp/SncpRequest.java @@ -9,7 +9,8 @@ import java.io.Serializable; import java.nio.ByteBuffer; import java.util.Objects; import java.util.logging.Level; -import org.redkale.convert.bson.*; +import org.redkale.convert.*; +import org.redkale.convert.bson.BsonReader; import org.redkale.net.Request; import static org.redkale.net.sncp.SncpHeader.HEADER_SIZE; import org.redkale.util.Uint128; @@ -125,11 +126,11 @@ public class SncpRequest extends Request { return ping; } - public BsonConvert getBsonConvert() { + public Convert getConvert() { return context.getBsonConvert(); } - public BsonReader getBsonReader() { + public Reader getReader() { return body == null ? null : reader.setBytes(body); } diff --git a/src/test/java/org/redkale/test/sncp/TestService.java b/src/test/java/org/redkale/test/sncp/TestService.java index 5a72da9e3..49113a87b 100644 --- a/src/test/java/org/redkale/test/sncp/TestService.java +++ b/src/test/java/org/redkale/test/sncp/TestService.java @@ -7,7 +7,7 @@ import java.lang.reflect.Method; import java.nio.channels.CompletionHandler; import java.util.concurrent.CompletableFuture; import org.redkale.annotation.ResourceType; -import org.redkale.convert.bson.*; +import org.redkale.convert.*; import org.redkale.net.sncp.SncpDynServlet.SncpActionServlet; import org.redkale.net.sncp.*; import org.redkale.service.Service; @@ -70,8 +70,8 @@ public interface TestService extends Service { @Override public void action(SncpRequest request, SncpResponse response) throws Throwable { - BsonConvert convert = request.getBsonConvert(); - BsonReader in = request.getBsonReader(); + Convert convert = request.getConvert(); + Reader in = request.getReader(); TestBean arg1 = convert.convertFrom(paramTypes[1], in); String arg2 = convert.convertFrom(paramTypes[2], in); int arg3 = convert.convertFrom(paramTypes[3], in); @@ -89,8 +89,8 @@ public interface TestService extends Service { @Override public void action(SncpRequest request, SncpResponse response) throws Throwable { - BsonConvert convert = request.getBsonConvert(); - BsonReader in = request.getBsonReader(); + Convert convert = request.getConvert(); + Reader in = request.getReader(); BooleanHandler arg0 = response.getParamAsyncHandler(); convert.convertFrom(CompletionHandler.class, in); TestBean arg1 = convert.convertFrom(paramTypes[2], in); @@ -110,8 +110,8 @@ public interface TestService extends Service { @Override public void action(SncpRequest request, SncpResponse response) throws Throwable { - BsonConvert convert = request.getBsonConvert(); - BsonReader in = request.getBsonReader(); + Convert convert = request.getConvert(); + Reader in = request.getReader(); long a1 = convert.convertFrom(paramTypes[1], in); short a2 = convert.convertFrom(paramTypes[2], in); CompletionHandler a3 = response.getParamAsyncHandler(); @@ -133,8 +133,8 @@ public interface TestService extends Service { @Override public void action(SncpRequest request, SncpResponse response) throws Throwable { - BsonConvert convert = request.getBsonConvert(); - BsonReader in = request.getBsonReader(); + Convert convert = request.getConvert(); + Reader in = request.getReader(); TestBean arg1 = convert.convertFrom(paramTypes[1], in); String arg2 = convert.convertFrom(paramTypes[2], in); int arg3 = convert.convertFrom(paramTypes[3], in);