From 7ce808e257e3ab29458387b199699c3b5c833762 Mon Sep 17 00:00:00 2001 From: Nicolas Feybesse Date: Mon, 5 Sep 2016 12:46:34 +0200 Subject: [PATCH] Prepare real time feature --- .../common/AbstractWebSocketsServer.java | 6 +- .../genericsystem/kernel/EngineServer.java | 19 +- .../reactor/appserver/ApplicationServer.java | 181 ++++++++++-------- 3 files changed, 118 insertions(+), 88 deletions(-) diff --git a/gs-common/src/main/java/org/genericsystem/common/AbstractWebSocketsServer.java b/gs-common/src/main/java/org/genericsystem/common/AbstractWebSocketsServer.java index bbbd362f2..4ee15a210 100644 --- a/gs-common/src/main/java/org/genericsystem/common/AbstractWebSocketsServer.java +++ b/gs-common/src/main/java/org/genericsystem/common/AbstractWebSocketsServer.java @@ -32,6 +32,8 @@ public AbstractWebSocketsServer(String host, int port) { public abstract Handler getHandler(String path, ServerWebSocket socket); + public abstract Handler getCloseHandler(ServerWebSocket socket); + public abstract void addHttpHandler(HttpServer httpServer); public void start() { @@ -48,6 +50,7 @@ public void start() { HttpServer httpServer = vertx.createHttpServer(new HttpServerOptions().setPort(port).setHost(host)); httpServer.websocketHandler(webSocket -> { + String path = webSocket.path(); webSocket.handler(getHandler(path, webSocket)); webSocket.exceptionHandler(e -> { @@ -55,8 +58,7 @@ public void start() { throw new IllegalStateException(e); }); - webSocket.closeHandler((v) -> System.out.println("close the webSocket")); - ; + webSocket.closeHandler(getCloseHandler(webSocket)); }); addHttpHandler(httpServer); diff --git a/gs-kernel/src/main/java/org/genericsystem/kernel/EngineServer.java b/gs-kernel/src/main/java/org/genericsystem/kernel/EngineServer.java index 73e213772..c40cf9bfc 100644 --- a/gs-kernel/src/main/java/org/genericsystem/kernel/EngineServer.java +++ b/gs-kernel/src/main/java/org/genericsystem/kernel/EngineServer.java @@ -1,12 +1,9 @@ package org.genericsystem.kernel; -import io.vertx.core.Handler; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.HttpServer; -import io.vertx.core.http.ServerWebSocket; - import java.util.Collections; import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.genericsystem.common.AbstractBackEnd; import org.genericsystem.common.AbstractCache; @@ -16,12 +13,19 @@ import org.genericsystem.common.GSBuffer; import org.genericsystem.common.Protocol; +import io.vertx.core.Handler; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.HttpServer; +import io.vertx.core.http.ServerWebSocket; + /** * @author Nicolas Feybesse * */ public class EngineServer extends AbstractBackEnd { + private Set caches = Collections.newSetFromMap(new ConcurrentHashMap()); + public static void main(String[] args) { new EngineServer(new DefaultPathSingleEngineDeployment("/", null)).start(); } @@ -95,6 +99,11 @@ public void addHttpHandler(HttpServer httpServer) { // TODO Auto-generated method stub } + + @Override + public Handler getCloseHandler(ServerWebSocket socket) { + return (v) -> System.out.println("Close socket"); + } } @Override diff --git a/gs-reactor/src/main/java/org/genericsystem/reactor/appserver/ApplicationServer.java b/gs-reactor/src/main/java/org/genericsystem/reactor/appserver/ApplicationServer.java index 4f90bf4b9..96a9e8096 100644 --- a/gs-reactor/src/main/java/org/genericsystem/reactor/appserver/ApplicationServer.java +++ b/gs-reactor/src/main/java/org/genericsystem/reactor/appserver/ApplicationServer.java @@ -1,15 +1,5 @@ package org.genericsystem.reactor.appserver; -import io.vertx.core.Handler; -import io.vertx.core.MultiMap; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.HttpHeaders; -import io.vertx.core.http.HttpServer; -import io.vertx.core.http.ServerWebSocket; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -18,18 +8,29 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.genericsystem.common.AbstractBackEnd; -import org.genericsystem.common.AbstractCache; import org.genericsystem.common.AbstractWebSocketsServer; import org.genericsystem.common.GSBuffer; import org.genericsystem.common.Root; +import org.genericsystem.kernel.Cache; import org.genericsystem.reactor.HtmlDomNode; import org.genericsystem.reactor.HtmlDomNode.RootHtmlDomNode; import org.genericsystem.reactor.appserver.WebAppsConfig.SimpleWebAppConfig; import org.genericsystem.reactor.gs.GSApp; +import io.vertx.core.Handler; +import io.vertx.core.MultiMap; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.HttpHeaders; +import io.vertx.core.http.HttpServer; +import io.vertx.core.http.ServerWebSocket; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + /** * @author Nicolas Feybesse * @@ -76,8 +77,17 @@ protected Root buildRoot(String persistentDirectoryPath, Set> userClass private class WebSocketsServer extends AbstractWebSocketsServer { + public void cachesShiftTs() { + for (Cache cache : caches.values()) { + cache.shiftTs(); + } + } + + private Map caches = new ConcurrentHashMap(); + public WebSocketsServer(String host, int port) { super(host, port); + // GSVertx.vertx().getVertx().setPeriodic(5000, l -> cachesShiftTs()); } @Override @@ -87,8 +97,9 @@ public Handler getHandler(String path, ServerWebSocket socket) { if (application == null) { throw new IllegalStateException("Unable to load an application with path : " + path); } - AbstractCache cache = application.getEngine().newCache(); + Cache cache = (Cache) application.getEngine().newCache(); RootHtmlDomNode rootHtmlDomNode = cache.safeSupply(() -> application.init(socket)); + caches.put(socket, cache); // log.info("Open new socket : " + socket); return buffer -> { // log.info("Receive new message for socket : " + socket); @@ -103,82 +114,90 @@ public Handler getHandler(String path, ServerWebSocket socket) { }; } + @Override + public Handler getCloseHandler(ServerWebSocket socket) { + return (v) -> { + System.out.println("Close socket"); + caches.remove(socket); + }; + } + @Override public void addHttpHandler(HttpServer httpServer) { httpServer.requestHandler(request -> { // log.info("Request received with path : " + request.path()); - String[] items = request.path().substring(1).split("/"); - // log.info("Request received with splited items : " + Arrays.toString(items)); - String appPath = items.length == 0 ? "" : items[0]; - if (appPath.endsWith(".js") || appPath.endsWith(".css") || appPath.endsWith(".ico") || appPath.endsWith(".jpg") || appPath.endsWith(".png")) - appPath = ""; - // log.info("Request received with application path : " + appPath); - PersistentApplication application = apps.get("/" + appPath); - if (application == null) { - request.response().end("No application is configured with path : /" + appPath); - log.info("No application is configured with path : /" + appPath); - return; + String[] items = request.path().substring(1).split("/"); + // log.info("Request received with splited items : " + Arrays.toString(items)); + String appPath = items.length == 0 ? "" : items[0]; + if (appPath.endsWith(".js") || appPath.endsWith(".css") || appPath.endsWith(".ico") || appPath.endsWith(".jpg") || appPath.endsWith(".png")) + appPath = ""; + // log.info("Request received with application path : " + appPath); + PersistentApplication application = apps.get("/" + appPath); + if (application == null) { + request.response().end("No application is configured with path : /" + appPath); + log.info("No application is configured with path : /" + appPath); + return; + } + // log.info("Request detected for application : " + application.getApplicationClass().getName()); + int shift = appPath.isEmpty() ? 0 : 1; + shift += items.length > shift ? 1 : 0; + String resourceToServe = request.path().substring(appPath.length() + shift); + // log.info("Resource to serve : " + resourceToServe); + if ("".equals(resourceToServe)) { + String indexHtml = ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + indexHtml += ""; + request.response().end(indexHtml); + } else { + InputStream input = application.getApplicationClass().getResourceAsStream("/" + resourceToServe); + if (input == null) { + if (resourceToServe.endsWith(".css")) { + log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard reactor.css instead"); + input = ApplicationServer.class.getResourceAsStream("/reactor.css"); + } else if (resourceToServe.endsWith(".js")) { + log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard script.js instead"); + input = ApplicationServer.class.getResourceAsStream("/script.js"); + } else if (resourceToServe.endsWith("favicon.ico")) { + log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard favicon.ico instead"); + input = ApplicationServer.class.getResourceAsStream("/favicon.ico"); + } else if (resourceToServe.endsWith(".ico") || resourceToServe.endsWith(".jpg") || resourceToServe.endsWith(".png")) { + log.warn("Unable to find resource : /" + resourceToServe + ", get nothing instead"); + request.response().end(); + return; + } else + throw new IllegalStateException("Unable to find resource : " + resourceToServe); } - // log.info("Request detected for application : " + application.getApplicationClass().getName()); - int shift = appPath.isEmpty() ? 0 : 1; - shift += items.length > shift ? 1 : 0; - String resourceToServe = request.path().substring(appPath.length() + shift); - // log.info("Resource to serve : " + resourceToServe); - if ("".equals(resourceToServe)) { - String indexHtml = ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - indexHtml += ""; - request.response().end(indexHtml); + if (resourceToServe.endsWith(".ico")) { + MultiMap headers = request.response().headers(); + Buffer buffer = makeBuffer(input); + headers.add(HttpHeaders.CONTENT_TYPE, "image/x-icon"); + headers.add(HttpHeaders.CONTENT_LENGTH, Integer.toString(buffer.length())); + headers.add(HttpHeaders.CACHE_CONTROL, "public, max-age=" + 86400); + request.response().end(buffer); + } else if (resourceToServe.endsWith(".jpg") || resourceToServe.endsWith(".png")) { + // TODO + MultiMap headers = request.response().headers(); + Buffer buffer = makeBuffer(input); + // headers.add(HttpHeaders.CONTENT_TYPE, "image/x-icon"); + headers.add(HttpHeaders.CONTENT_LENGTH, Integer.toString(buffer.length())); + headers.add(HttpHeaders.CACHE_CONTROL, "public, max-age=" + 86400); + request.response().end(buffer); } else { - InputStream input = application.getApplicationClass().getResourceAsStream("/" + resourceToServe); - if (input == null) { - if (resourceToServe.endsWith(".css")) { - log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard reactor.css instead"); - input = ApplicationServer.class.getResourceAsStream("/reactor.css"); - } else if (resourceToServe.endsWith(".js")) { - log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard script.js instead"); - input = ApplicationServer.class.getResourceAsStream("/script.js"); - } else if (resourceToServe.endsWith("favicon.ico")) { - log.warn("Unable to find resource : /" + resourceToServe + ", get the reactor standard favicon.ico instead"); - input = ApplicationServer.class.getResourceAsStream("/favicon.ico"); - } else if (resourceToServe.endsWith(".ico") || resourceToServe.endsWith(".jpg") || resourceToServe.endsWith(".png")) { - log.warn("Unable to find resource : /" + resourceToServe + ", get nothing instead"); - request.response().end(); - return; - } else - throw new IllegalStateException("Unable to find resource : " + resourceToServe); - } - if (resourceToServe.endsWith(".ico")) { - MultiMap headers = request.response().headers(); - Buffer buffer = makeBuffer(input); - headers.add(HttpHeaders.CONTENT_TYPE, "image/x-icon"); - headers.add(HttpHeaders.CONTENT_LENGTH, Integer.toString(buffer.length())); - headers.add(HttpHeaders.CACHE_CONTROL, "public, max-age=" + 86400); - request.response().end(buffer); - } else if (resourceToServe.endsWith(".jpg") || resourceToServe.endsWith(".png")) { - // TODO - MultiMap headers = request.response().headers(); - Buffer buffer = makeBuffer(input); - // headers.add(HttpHeaders.CONTENT_TYPE, "image/x-icon"); - headers.add(HttpHeaders.CONTENT_LENGTH, Integer.toString(buffer.length())); - headers.add(HttpHeaders.CACHE_CONTROL, "public, max-age=" + 86400); - request.response().end(buffer); - } else { - String result = new BufferedReader(new InputStreamReader(input)).lines().collect(Collectors.joining("\n")); - request.response().end(result); - } + String result = new BufferedReader(new InputStreamReader(input)).lines().collect(Collectors.joining("\n")); + request.response().end(result); } - }); + } + }); } private Buffer makeBuffer(InputStream input) {