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