This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.wentch.redkale.boot;
|
package com.wentch.redkale.boot;
|
||||||
|
|
||||||
|
import com.wentch.redkale.boot.ClassFilter.FilterEntry;
|
||||||
import com.wentch.redkale.convert.bson.*;
|
import com.wentch.redkale.convert.bson.*;
|
||||||
import com.wentch.redkale.convert.json.*;
|
import com.wentch.redkale.convert.json.*;
|
||||||
import com.wentch.redkale.net.*;
|
import com.wentch.redkale.net.*;
|
||||||
@@ -21,6 +22,7 @@ import java.nio.channels.*;
|
|||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.*;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import javax.xml.parsers.*;
|
import javax.xml.parsers.*;
|
||||||
import org.w3c.dom.*;
|
import org.w3c.dom.*;
|
||||||
@@ -391,6 +393,8 @@ public final class Application {
|
|||||||
private void runServers(CountDownLatch timecd, final List<AnyValue> serconfs) throws Exception {
|
private void runServers(CountDownLatch timecd, final List<AnyValue> serconfs) throws Exception {
|
||||||
this.servicecdl = new CountDownLatch(serconfs.size());
|
this.servicecdl = new CountDownLatch(serconfs.size());
|
||||||
CountDownLatch sercdl = new CountDownLatch(serconfs.size());
|
CountDownLatch sercdl = new CountDownLatch(serconfs.size());
|
||||||
|
final AtomicBoolean inited = new AtomicBoolean(false);
|
||||||
|
final Map<String, Class<? extends NodeServer>> nodeClasses = new HashMap<>();
|
||||||
for (final AnyValue serconf : serconfs) {
|
for (final AnyValue serconf : serconfs) {
|
||||||
Thread thread = new Thread() {
|
Thread thread = new Thread() {
|
||||||
{
|
{
|
||||||
@@ -410,6 +414,28 @@ public final class Application {
|
|||||||
server = new NodeSncpServer(Application.this, serconf);
|
server = new NodeSncpServer(Application.this, serconf);
|
||||||
} else if ("HTTP".equalsIgnoreCase(protocol)) {
|
} else if ("HTTP".equalsIgnoreCase(protocol)) {
|
||||||
server = new NodeHttpServer(Application.this, serconf);
|
server = new NodeHttpServer(Application.this, serconf);
|
||||||
|
} else {
|
||||||
|
if (!inited.get()) {
|
||||||
|
synchronized (nodeClasses) {
|
||||||
|
if (!inited.get()) {
|
||||||
|
inited.set(true);
|
||||||
|
ClassFilter profilter = new ClassFilter(NodeProtocol.class, NodeServer.class);
|
||||||
|
ClassFilter.Loader.load(home, profilter);
|
||||||
|
final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys();
|
||||||
|
for (FilterEntry<NodeServer> entry : entrys) {
|
||||||
|
final Class<? extends NodeServer> type = entry.getType();
|
||||||
|
NodeProtocol pros = type.getAnnotation(NodeProtocol.class);
|
||||||
|
for (String p : pros.value()) {
|
||||||
|
final Class<? extends NodeServer> old = nodeClasses.get(p);
|
||||||
|
if (old != null && old != type) throw new RuntimeException("Protocol(" + p + ") had NodeServer-Class(" + old.getName() + ") but repeat NodeServer-Class(" + type.getName() + ")");
|
||||||
|
nodeClasses.put(p, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Class<? extends NodeServer> nodeClass = nodeClasses.get(protocol);
|
||||||
|
if (nodeClass != null) server = NodeServer.create(nodeClass, Application.this, serconf);
|
||||||
}
|
}
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
logger.log(Level.SEVERE, "Not found Server Class for protocol({0})", serconf.getValue("protocol"));
|
logger.log(Level.SEVERE, "Not found Server Class for protocol({0})", serconf.getValue("protocol"));
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.lang.annotation.*;
|
|||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
import java.util.jar.*;
|
import java.util.jar.*;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import java.util.regex.*;
|
import java.util.regex.*;
|
||||||
@@ -322,6 +323,12 @@ public final class ClassFilter<T> {
|
|||||||
|
|
||||||
protected static final Logger logger = Logger.getLogger(Loader.class.getName());
|
protected static final Logger logger = Logger.getLogger(Loader.class.getName());
|
||||||
|
|
||||||
|
protected static final ConcurrentMap<URL, Set<String>> cache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static void close() {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载当前线程的classpath扫描所有class进行过滤
|
* 加载当前线程的classpath扫描所有class进行过滤
|
||||||
* <p>
|
* <p>
|
||||||
@@ -346,33 +353,69 @@ public final class ClassFilter<T> {
|
|||||||
List<File> files = new ArrayList<>();
|
List<File> files = new ArrayList<>();
|
||||||
boolean debug = logger.isLoggable(Level.FINEST);
|
boolean debug = logger.isLoggable(Level.FINEST);
|
||||||
StringBuilder debugstr = new StringBuilder();
|
StringBuilder debugstr = new StringBuilder();
|
||||||
for (URL url : urljares) {
|
for (final URL url : urljares) {
|
||||||
try (JarFile jar = new JarFile(URLDecoder.decode(url.getFile(), "UTF-8"))) {
|
Set<String> classes = cache.get(url);
|
||||||
Enumeration<JarEntry> it = jar.entries();
|
if (classes == null) {
|
||||||
while (it.hasMoreElements()) {
|
synchronized (cache) {
|
||||||
String entryname = it.nextElement().getName().replace('/', '.');
|
if (cache.get(url) == null) {
|
||||||
if (entryname.endsWith(".class") && entryname.indexOf('$') < 0) {
|
classes = new CopyOnWriteArraySet<>();
|
||||||
String classname = entryname.substring(0, entryname.length() - 6);
|
cache.put(url, classes);
|
||||||
if (classname.startsWith("javax.") || classname.startsWith("org.") || classname.startsWith("com.mysql.")) continue;
|
} else {
|
||||||
if (debug) debugstr.append(classname).append("\r\n");
|
classes = cache.get(url);
|
||||||
for (final ClassFilter filter : filters) {
|
}
|
||||||
if (filter != null) filter.filter(null, classname);
|
}
|
||||||
|
try (JarFile jar = new JarFile(URLDecoder.decode(url.getFile(), "UTF-8"))) {
|
||||||
|
Enumeration<JarEntry> it = jar.entries();
|
||||||
|
while (it.hasMoreElements()) {
|
||||||
|
String entryname = it.nextElement().getName().replace('/', '.');
|
||||||
|
if (entryname.endsWith(".class") && entryname.indexOf('$') < 0) {
|
||||||
|
String classname = entryname.substring(0, entryname.length() - 6);
|
||||||
|
if (classname.startsWith("javax.") || classname.startsWith("org.") || classname.startsWith("com.mysql.")) continue;
|
||||||
|
classes.add(classname);
|
||||||
|
if (debug) debugstr.append(classname).append("\r\n");
|
||||||
|
for (final ClassFilter filter : filters) {
|
||||||
|
if (filter != null) filter.filter(null, classname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (String classname : classes) {
|
||||||
|
for (final ClassFilter filter : filters) {
|
||||||
|
if (filter != null) filter.filter(null, classname);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (URL url : urlfiles) {
|
for (final URL url : urlfiles) {
|
||||||
files.clear();
|
Set<String> classes = cache.get(url);
|
||||||
File root = new File(url.getFile());
|
if (classes == null) {
|
||||||
String rootpath = root.getPath();
|
synchronized (cache) {
|
||||||
loadClassFiles(exclude, root, files);
|
if (cache.get(url) == null) {
|
||||||
for (File f : files) {
|
classes = new CopyOnWriteArraySet<>();
|
||||||
String classname = f.getPath().substring(rootpath.length() + 1, f.getPath().length() - 6).replace(File.separatorChar, '.');
|
cache.put(url, classes);
|
||||||
if (classname.startsWith("javax.") || classname.startsWith("org.") || classname.startsWith("com.mysql.")) continue;
|
} else {
|
||||||
if (debug) debugstr.append(classname).append("\r\n");
|
classes = cache.get(url);
|
||||||
for (final ClassFilter filter : filters) {
|
}
|
||||||
if (filter != null) filter.filter(null, classname);
|
}
|
||||||
|
files.clear();
|
||||||
|
File root = new File(url.getFile());
|
||||||
|
String rootpath = root.getPath();
|
||||||
|
loadClassFiles(exclude, root, files);
|
||||||
|
for (File f : files) {
|
||||||
|
String classname = f.getPath().substring(rootpath.length() + 1, f.getPath().length() - 6).replace(File.separatorChar, '.');
|
||||||
|
if (classname.startsWith("javax.") || classname.startsWith("org.") || classname.startsWith("com.mysql.")) continue;
|
||||||
|
classes.add(classname);
|
||||||
|
if (debug) debugstr.append(classname).append("\r\n");
|
||||||
|
for (final ClassFilter filter : filters) {
|
||||||
|
if (filter != null) filter.filter(null, classname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (String classname : classes) {
|
||||||
|
for (final ClassFilter filter : filters) {
|
||||||
|
if (filter != null) filter.filter(null, classname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import javax.annotation.*;
|
|||||||
*
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
*/
|
*/
|
||||||
|
@NodeProtocol({"HTTP", "HTTPS"})
|
||||||
public final class NodeHttpServer extends NodeServer {
|
public final class NodeHttpServer extends NodeServer {
|
||||||
|
|
||||||
private final HttpServer httpServer;
|
private final HttpServer httpServer;
|
||||||
|
|||||||
19
src/com/wentch/redkale/boot/NodeProtocol.java
Normal file
19
src/com/wentch/redkale/boot/NodeProtocol.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.wentch.redkale.boot;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface NodeProtocol {
|
||||||
|
String[] value();
|
||||||
|
}
|
||||||
@@ -73,6 +73,14 @@ public abstract class NodeServer {
|
|||||||
this.fine = logger.isLoggable(Level.FINE);
|
this.fine = logger.isLoggable(Level.FINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends NodeServer> NodeServer create(Class<T> clazz, Application application, AnyValue serconf) {
|
||||||
|
try {
|
||||||
|
return clazz.getConstructor(Application.class, AnyValue.class).newInstance(application, serconf);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void init(AnyValue config) throws Exception {
|
public void init(AnyValue config) throws Exception {
|
||||||
this.nodeConf = config == null ? AnyValue.create() : config;
|
this.nodeConf = config == null ? AnyValue.create() : config;
|
||||||
if (isSNCP()) { // SNCP协议
|
if (isSNCP()) { // SNCP协议
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.logging.*;
|
|||||||
*
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
*/
|
*/
|
||||||
|
@NodeProtocol({"SNCP"})
|
||||||
public final class NodeSncpServer extends NodeServer {
|
public final class NodeSncpServer extends NodeServer {
|
||||||
|
|
||||||
private final SncpServer sncpServer;
|
private final SncpServer sncpServer;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import java.nio.*;
|
|||||||
*
|
*
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
*/
|
*/
|
||||||
@AutoLoad(false)
|
|
||||||
public class BindingIcepServlet extends IcepServlet {
|
public class BindingIcepServlet extends IcepServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,14 +19,17 @@ public class IcepPrepareServlet extends PrepareServlet<IcepRequest, IcepResponse
|
|||||||
private final HashMap<Short, IcepServlet> servletmaps = new HashMap<>();
|
private final HashMap<Short, IcepServlet> servletmaps = new HashMap<>();
|
||||||
|
|
||||||
public IcepPrepareServlet() {
|
public IcepPrepareServlet() {
|
||||||
BindingIcepServlet servlet = new BindingIcepServlet();
|
|
||||||
this.servletmaps.put(servlet.getRequestid(), new BindingIcepServlet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Context context, AnyValue config) {
|
public void init(Context context, AnyValue config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addIcepServlet(IcepServlet servlet, AnyValue conf) {
|
||||||
|
servlet.conf = conf;
|
||||||
|
this.servletmaps.put(servlet.getRequestid(), servlet);
|
||||||
|
}
|
||||||
|
|
||||||
// 28.[00,03,00,08, 21,12,a4,42,45,6f,4e,77,4e,47,71,55,32,37,77,39, 00,19,00,04,11,00,00,00]
|
// 28.[00,03,00,08, 21,12,a4,42,45,6f,4e,77,4e,47,71,55,32,37,77,39, 00,19,00,04,11,00,00,00]
|
||||||
@Override
|
@Override
|
||||||
public void execute(IcepRequest request, IcepResponse response) throws IOException {
|
public void execute(IcepRequest request, IcepResponse response) throws IOException {
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ public final class IcepServer extends Server {
|
|||||||
public IcepServer() {
|
public IcepServer() {
|
||||||
this(System.currentTimeMillis(), null);
|
this(System.currentTimeMillis(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
"content":"{\"cmd\":\"icecandidate\",\"candidate\":{\"candidate\":\"candidate:3791502225 1 tcp 1518214911 10.28.2.207 0 typ host tcptype active generation 0\",\"sdpMid\":\"video\",\"sdpMLineIndex\":1}}"
|
"content":"{\"cmd\":\"icecandidate\",\"candidate\":{\"candidate\":\"candidate:3791502225 1 tcp 1518214911 10.28.2.207 0 typ host tcptype active generation 0\",\"sdpMid\":\"video\",\"sdpMLineIndex\":1}}"
|
||||||
@param args
|
@param args
|
||||||
@throws Exception
|
@throws Exception
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
DefaultAnyValue conf = new DefaultAnyValue();
|
DefaultAnyValue conf = new DefaultAnyValue();
|
||||||
conf.addValue("host", "10.28.2.207");
|
conf.addValue("host", "10.28.2.207");
|
||||||
@@ -34,6 +35,7 @@ public final class IcepServer extends Server {
|
|||||||
final CountDownLatch cdl = new CountDownLatch(1);
|
final CountDownLatch cdl = new CountDownLatch(1);
|
||||||
final IcepServer server = new IcepServer();
|
final IcepServer server = new IcepServer();
|
||||||
server.init(conf);
|
server.init(conf);
|
||||||
|
server.addIcepServlet(new BindingIcepServlet(), null);
|
||||||
server.start();
|
server.start();
|
||||||
cdl.await();
|
cdl.await();
|
||||||
}
|
}
|
||||||
@@ -47,6 +49,10 @@ public final class IcepServer extends Server {
|
|||||||
super.init(config);
|
super.init(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addIcepServlet(IcepServlet servlet, AnyValue conf) {
|
||||||
|
((IcepPrepareServlet) this.prepare).addIcepServlet(servlet, conf);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected Context createContext() {
|
protected Context createContext() {
|
||||||
|
|||||||
72
src/com/wentch/redkale/net/icep/NodeIcepServer.java
Normal file
72
src/com/wentch/redkale/net/icep/NodeIcepServer.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.wentch.redkale.net.icep;
|
||||||
|
|
||||||
|
import com.wentch.redkale.boot.*;
|
||||||
|
import com.wentch.redkale.boot.ClassFilter.FilterEntry;
|
||||||
|
import com.wentch.redkale.net.*;
|
||||||
|
import com.wentch.redkale.util.*;
|
||||||
|
import com.wentch.redkale.util.AnyValue.DefaultAnyValue;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
@NodeProtocol({"ICEP"})
|
||||||
|
public class NodeIcepServer extends NodeServer {
|
||||||
|
|
||||||
|
private final IcepServer icepServer;
|
||||||
|
|
||||||
|
public NodeIcepServer(Application application, AnyValue serconf) {
|
||||||
|
super(application, application.getResourceFactory().createChild(), createServer(application, serconf));
|
||||||
|
this.icepServer = (IcepServer) server;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Server createServer(Application application, AnyValue serconf) {
|
||||||
|
return new IcepServer(application.getStartTime(), application.getWatchFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetSocketAddress getSocketAddress() {
|
||||||
|
return icepServer == null ? null : icepServer.getSocketAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClassFilter<Servlet> createServletClassFilter() {
|
||||||
|
return createClassFilter(null, null, IcepServlet.class, null, "servlets", "servlet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception {
|
||||||
|
if (icepServer != null) loadIcepServlet(this.nodeConf.getAnyValue("servlets"), servletFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadIcepServlet(final AnyValue conf, ClassFilter<? extends Servlet> filter) throws Exception {
|
||||||
|
final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null;
|
||||||
|
final String threadName = "[" + Thread.currentThread().getName() + "] ";
|
||||||
|
for (FilterEntry<? extends Servlet> en : filter.getFilterEntrys()) {
|
||||||
|
Class<IcepServlet> clazz = (Class<IcepServlet>) en.getType();
|
||||||
|
if (Modifier.isAbstract(clazz.getModifiers())) continue;
|
||||||
|
final IcepServlet servlet = clazz.newInstance();
|
||||||
|
factory.inject(servlet);
|
||||||
|
DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty();
|
||||||
|
this.icepServer.addIcepServlet(servlet, servletConf);
|
||||||
|
if (sb != null) sb.append(threadName).append(" Loaded ").append(clazz.getName()).append(" --> ").append(format(servlet.getRequestid())).append(LINE_SEPARATOR);
|
||||||
|
}
|
||||||
|
if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format(short value) {
|
||||||
|
String str = Integer.toHexString(value);
|
||||||
|
if (str.length() == 1) return "0x000" + str;
|
||||||
|
if (str.length() == 2) return "0x00" + str;
|
||||||
|
if (str.length() == 3) return "0x0" + str;
|
||||||
|
return "0x" + str;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user