diff --git a/labs/vertx-akka/build.sbt b/labs/vertx-akka/build.sbt index b2abf21ea4b020c79aa060d58f97cbc4a15a66b6..7950697d09da3a6dd31342dce87b27cb5a991b58 100755 --- a/labs/vertx-akka/build.sbt +++ b/labs/vertx-akka/build.sbt @@ -56,6 +56,7 @@ libraryDependencies ++= { "io.vertx" % "vertx-web" % vertxV, "io.vertx" % "vertx-auth-common" % vertxV, "io.vertx" % "vertx-auth-shiro" % vertxV, + "io.vertx" %% "vertx-web-scala" % vertxV, "io.vertx" %% "vertx-lang-scala" % vertxV, "com.github.etaty" % "rediscala_2.12" % "1.8.0", "com.softwaremill.quicklens" %% "quicklens" % "1.4.8", diff --git a/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/PrivateVerticle.java b/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/PrivateVerticle.java index eed5c51b5ecda18ce25672a2ca41029b429e3aa1..7793200328106ca405801b77abefb58ef997bf1d 100755 --- a/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/PrivateVerticle.java +++ b/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/PrivateVerticle.java @@ -161,4 +161,6 @@ public class PrivateVerticle extends AbstractVerticle { // Serve the non private static pages router.route().handler(StaticHandler.create()); } + + } diff --git a/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/SockJSHandlerVerticle.java b/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/SockJSHandlerVerticle.java new file mode 100755 index 0000000000000000000000000000000000000000..d080404ac7bbf6d962ba31a89e8329a8f32d69df --- /dev/null +++ b/labs/vertx-akka/src/main/java/org/bigbluebutton/vertx/SockJSHandlerVerticle.java @@ -0,0 +1,123 @@ +package org.bigbluebutton.vertx; + +import io.vertx.core.AbstractVerticle; +import io.vertx.core.eventbus.EventBus; +import io.vertx.ext.bridge.BridgeEventType; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.handler.BodyHandler; +import io.vertx.ext.web.handler.CookieHandler; +import io.vertx.ext.web.handler.SessionHandler; +import io.vertx.ext.web.handler.StaticHandler; +import io.vertx.ext.web.handler.sockjs.BridgeOptions; +import io.vertx.ext.web.handler.sockjs.PermittedOptions; +import io.vertx.ext.web.handler.sockjs.SockJSHandler; +import io.vertx.ext.web.handler.sockjs.SockJSHandlerOptions; +import io.vertx.ext.web.sstore.LocalSessionStore; +import org.bigbluebutton.ConnectionManager; +import org.bigbluebutton.VertxToAkkaGateway; + +import java.text.DateFormat; +import java.time.Instant; +import java.util.Date; + +public class SockJSHandlerVerticle extends AbstractVerticle { + private final ConnectionManager gw; + + public SockJSHandlerVerticle(ConnectionManager gw) { + this.gw = gw; + } + + @Override + public void start() throws Exception { + + Router router = Router.router(vertx); + + // We need cookies, sessions and request bodies + router.route().handler(CookieHandler.create()); + router.route().handler(BodyHandler.create()); + router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))); + + // Simple auth service which uses a properties file for user/role info + //AuthProvider authProvider = new MyAuthProvider(vertx); + + // We need a user session handler too to make sure the user is stored in the session between requests + //router.route().handler(UserSessionHandler.create(authProvider)); + + // Allow events for the designated addresses in/out of the event bus bridge + BridgeOptions opts = new BridgeOptions() + .addInboundPermitted(new PermittedOptions().setAddress("chat.to.server")) + .addOutboundPermitted(new PermittedOptions().setAddress("chat.to.client")); + + SockJSHandlerOptions options = new SockJSHandlerOptions().setHeartbeatInterval(2000); + + // Create the event bus bridge and add it to the router. + SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options); + + router.route("/eventbus/*").handler(sockJSHandler); + + EventBus eb = vertx.eventBus(); + + sockJSHandler.bridge(opts, be -> { + if (be.type() == BridgeEventType.SOCKET_CREATED) { + System.out.println("Socket create for session: " + be.socket().webSession().id() + " socketWriteId:" + be.socket().writeHandlerID()); + eb.consumer(be.socket().webSession().id()).handler(message -> { + be.socket().close(); + }); + gw.connectionCreated(be.socket().webSession().id()); + } else if (be.type() == BridgeEventType.SOCKET_CLOSED) { + System.out.println("Socket closed for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + gw.connectionClosed(be.socket().webSession().id()); + eb.consumer(be.socket().webSession().id()).unregister(); + } else if (be.type() == BridgeEventType.SOCKET_IDLE) { + System.out.println("Socket SOCKET_IDLE for: " + be.socket().webSession().id()); + } else if (be.type() == BridgeEventType.SOCKET_PING) { + System.out.println("Socket SOCKET_PING for: " + be.socket().webSession().id()); + } else if (be.type() == BridgeEventType.UNREGISTER) { + System.out.println("Socket UNREGISTER for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } else if (be.type() == BridgeEventType.PUBLISH) { + System.out.println("Socket PUBLISH for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } else if (be.type() == BridgeEventType.RECEIVE) { + System.out.println("Socket RECEIVE for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } else if (be.type() == BridgeEventType.SEND) { + System.out.println("Socket SEND for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } else if (be.type() == BridgeEventType.REGISTER) { + System.out.println("Socket REGISTER for: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } else { + System.out.println("Message from: " + be.socket().webSession().id() + " \n " + be.getRawMessage()); + } + + + + // System.out.println("USER=" + be.socket().webUser().principal()); + + be.complete(true); + }); + + // Create a router endpoint for the static content. + router.route().handler(StaticHandler.create()); + + // Start the web server and tell it to use the router to handle requests. + //vertx.createHttpServer(new HttpServerOptions().setSsl(true).setKeyStoreOptions( + // new JksOptions().setPath("server-keystore.jks").setPassword("wibble") + // )).requestHandler(router::accept).listen(3001); + vertx.createHttpServer().requestHandler(router::accept).listen(3001); + + // Register to listen for messages coming IN to the server + eb.consumer("chat.to.server").handler(message -> { + // Create a timestamp string + String timestamp = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(Date.from(Instant.now())); + // Send the message back out to all clients with the timestamp prepended. + //gw.send("TO ECHO:" + timestamp + ": " + message.body()); + // eb.publish("foofoofoo", message.body()); + }); + + eb.consumer("to-vertx").handler(message -> { + eb.publish("chat.to.client", message.body()); + }); + + + // Serve the non private static pages + router.route().handler(StaticHandler.create()); + } + +} diff --git a/labs/vertx-akka/src/main/scala/org/bigbluebutton/Connection.scala b/labs/vertx-akka/src/main/scala/org/bigbluebutton/Connection.scala new file mode 100755 index 0000000000000000000000000000000000000000..9cbab3797206fc23ec3b442927dc29e389e219de --- /dev/null +++ b/labs/vertx-akka/src/main/scala/org/bigbluebutton/Connection.scala @@ -0,0 +1,15 @@ +package org.bigbluebutton + +import akka.actor.{Actor, ActorLogging, Props} + +object Connection { + def props(connId: String): Props = + Props(classOf[Connection]) +} + +class Connection(connId: String) extends Actor with ActorLogging { + + def receive = { + case _ => log.debug("***** Connection cannot handle msg ") + } +} diff --git a/labs/vertx-akka/src/main/scala/org/bigbluebutton/ConnectionManager.scala b/labs/vertx-akka/src/main/scala/org/bigbluebutton/ConnectionManager.scala new file mode 100755 index 0000000000000000000000000000000000000000..08115379a4664d670b1b2958d9f9decdced0ed9d --- /dev/null +++ b/labs/vertx-akka/src/main/scala/org/bigbluebutton/ConnectionManager.scala @@ -0,0 +1,19 @@ +package org.bigbluebutton + +import akka.actor.ActorSystem +import io.vertx.core.Vertx + +class ConnectionManager(system: ActorSystem, vertx: Vertx) { + + def connectionCreated(id: String):Unit = { + + } + + def connectionClosed(id: String):Unit = { + + } + + def onMessageReceived(id: String, msg: String):Unit = { + + } +} diff --git a/labs/vertx-akka/src/main/scala/org/bigbluebutton/SockJSHandlerVerticle.scala b/labs/vertx-akka/src/main/scala/org/bigbluebutton/SockJSHandlerVerticle.scala new file mode 100755 index 0000000000000000000000000000000000000000..36e8e376366117ecc702cd9c22b243260f1f2a7e --- /dev/null +++ b/labs/vertx-akka/src/main/scala/org/bigbluebutton/SockJSHandlerVerticle.scala @@ -0,0 +1,32 @@ +package org.bigbluebutton + +import io.vertx.ext.web.handler.{ BodyHandler, CookieHandler, SessionHandler } +import io.vertx.ext.web.sstore.LocalSessionStore +import io.vertx.lang.scala.ScalaVerticle +import io.vertx.scala.ext.web.Router + +class SockJSHandlerVerticle extends ScalaVerticle { + + override def start(): Unit = { + println("Starting") + //val router = Router.router(vertx) + + // We need cookies, sessions and request bodies + //router.route().handler(CookieHandler.create) + //router.route().handler(BodyHandler.create) + //router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))) + + // Simple auth service which uses a properties file for user/role info + //AuthProvider authProvider = new MyAuthProvider(vertx); + + // We need a user session handler too to make sure the user is stored in the session between requests + //router.route().handler(UserSessionHandler.create(authProvider)); + + // Handles the actual login + //router.route("/loginhandler").handler(FormLoginHandler.create(authProvider)); + } + + override def stop(): Unit = { + println("Stopping") + } +}