sncp优化

This commit is contained in:
redkale
2023-02-08 19:06:22 +08:00
parent 3ec4f9f96d
commit 67cd0b1b46
11 changed files with 62 additions and 1085 deletions

View File

@@ -126,7 +126,7 @@ public class NodeSncpServer extends NodeServer {
@Override
protected void loadServlet(ClassFilter<? extends Servlet> servletFilter, ClassFilter otherFilter) throws Exception {
RedkaleClassLoader.putReflectionPublicClasses(SncpServlet.class.getName());
RedkaleClassLoader.putReflectionPublicClasses(OldSncpDynServlet.class.getName());
RedkaleClassLoader.putReflectionPublicClasses(SncpDynServlet.class.getName());
}
@Override

View File

@@ -57,6 +57,8 @@ public abstract class Convert<R extends Reader, W extends Writer> {
public abstract <T> T convertFrom(final Type type, final byte[] bytes);
public abstract <T> T convertFrom(final Type type, final R reader);
//@since 2.2.0
public abstract <T> T convertFrom(final Type type, final byte[] bytes, final int offset, final int length);

View File

@@ -164,6 +164,7 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(mask, buffers));
}
@Override
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final BsonReader reader) {
if (type == null) {

View File

@@ -182,6 +182,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
return (T) decoder.convertFrom(new JsonByteBufferReader(mask, buffers));
}
@Override
public <T> T convertFrom(final Type type, final JsonReader reader) {
if (type == null) {
return null;

View File

@@ -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) + ")");

View File

@@ -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.*;
/**
* <blockquote><pre>
* public class TestService implements Service {
*
* public boolean change(TestBean bean, String name, int id) {
* return false;
* }
*
* public void insert(CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id) {
* }
*
* public void update(long show, short v2, CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id) {
* }
*
* public CompletableFuture&#60;String&#62; changeName(TestBean bean, String name, int id) {
* return null;
* }
* }
*
*
* class DynActionTestService_change extends SncpServletAction {
*
* public TestService service;
*
* &#064;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;
&#064;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;
&#064;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;
&#064;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);
}
}
</pre></blockquote>
*/
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<Uint128, SncpServletAction> 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<Uint128, Method> 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<OldSncpHandler> 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<OldSncpHandler> 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();
}
/**
* <blockquote><pre>
* public class TestService implements Service {
*
* public boolean change(TestBean bean, String name, int id) {
* return false;
* }
*
* public void insert(CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id) {
* }
*
* public void update(long show, short v2, CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id) {
* }
*
* public CompletableFuture&#60;String&#62; changeName(TestBean bean, String name, int id) {
* return null;
* }
* }
*
*
* class DynActionTestService_change extends SncpServletAction {
*
* public TestService service;
*
* &#064;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;
&#064;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;
&#064;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;
&#064;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);
}
}
</pre></blockquote>
*
* @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, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "()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); //不可能会发生
}
}
}
}

View File

@@ -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.*;
/**
* 异步回调函数 <br>
*
* public class _DyncSncpAsyncHandler extends XXXAsyncHandler implements SncpAsyncHandler
*
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <V> 结果对象的泛型
* @param <A> 附件对象的泛型
*/
public interface OldSncpHandler<V, A> extends CompletionHandler<V, A> {
public Object[] sncp_getParams();
public void sncp_setParams(Object... params);
public void sncp_setFuture(CompletableFuture future);
public CompletableFuture sncp_getFuture();
static class Factory {
/**
* <blockquote><pre>
考虑点:
1、CompletionHandler子类是接口且还有其他多个方法
2、CompletionHandler子类是类 需要继承,且必须有空参数构造函数
3、CompletionHandler子类无论是接口还是类都可能存在其他泛型
public class XXXAsyncHandler_DynSncpAsyncHandler extends XXXAsyncHandler implements OldSncpHandler {
private OldSncpHandler sncphandler;
private CompletableFuture sncpfuture;
&#64;ConstructorParameters({"sncphandler"})
public XXXAsyncHandler_DynSncpAsyncHandler(OldSncpHandler sncphandler) {
super();
this.sncphandler = sncphandler;
}
&#64;Override
* public void completed(Object result, Object attachment) {
* sncphandler.completed(result, attachment);
* }
*
* &#64;Override
* public void failed(Throwable exc, Object attachment) {
* sncphandler.failed(exc, attachment);
* }
*
* &#64;Override
* public Object[] sncp_getParams() {
* return sncphandler.sncp_getParams();
* }
*
* &#64;Override
* public void sncp_setParams(Object... params) {
* sncphandler.sncp_setParams(params);
* }
*
* &#64;Override
* public void sncp_setFuture(CompletableFuture future) {
* this.sncpfuture = future;
* }
*
* &#64;Override
* public CompletableFuture sncp_getFuture() {
* return this.sncpfuture;
* }
* }
*
* </pre></blockquote>
*
* @param handlerClass CompletionHandler类型或子类
*
* @return Creator
*/
public static Creator<OldSncpHandler> createCreator(Class<? extends CompletionHandler> 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, "<init>", "(" + 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, "<init>", "()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<OldSncpHandler> newClazz = (Class<OldSncpHandler>) 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<V, A> implements OldSncpHandler<V, A> {
//为了在回调函数中调用_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;
}
}
}

View File

@@ -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;

View File

@@ -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的值是clientSncpAddressSncpResponse的值是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
+ "}";
}

View File

@@ -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<SncpContext> {
return ping;
}
public BsonConvert getBsonConvert() {
public Convert getConvert() {
return context.getBsonConvert();
}
public BsonReader getBsonReader() {
public Reader getReader() {
return body == null ? null : reader.setBytes(body);
}

View File

@@ -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<Reader, Writer> 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<Reader, Writer> 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<Reader, Writer> 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<Reader, Writer> 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);