Fun With Scala and Vert.x

Vert.x is a polyglot event-driven application framework that runs on the Java Virtual Machine (JAVA 7 is the minimum supported version). Like Node.js, Vert.x is asynchronous and scalable, and lets developers build modern and effective web applications.

Being polyglot, Vert.x can be used in many flavors, among which : JavaScript,CoffeeScript, Ruby, Python,Groovy and Java. In order to enforce asynchronism and scalabity, Vert.x is built upon Netty, leverage the reactor pattern, using a frightening number of handlers.

This article aims at showing the powerful combination of Scala and Vert.x – the Java counterpart being provided as comparison.

Note : the source code are hosted on GitHub as part of lang-scala https://github.com/ouertani/vert.x/tree/master/vertx-lang/vertx-lang-scala

Vert.x supports many components :

  • WebSocket
  • HttpServer
  • Distributed Event Bus
  • TCP Server, SockJS ,… not presented here
  • I - WebSocket

    Web Socket are HTML 5 feature providing full-duplex communications. For old browsers that do not support WebSocket, Vert.x provides SockJS as out-of-the-box component.

    In order to run the following example check out : https://github.com/ouertani/vert.x/blob/master/vertx-examples/src/main/javascript/websockets/ws.html and save it into the compiled lib directory

    Java

    SampleWebSocket.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    import org.vertx.java.core.Handler;
    import org.vertx.java.core.buffer.Buffer;
    import org.vertx.java.core.http.HttpServerRequest;
    import org.vertx.java.core.http.ServerWebSocket;
    import org.vertx.java.deploy.Verticle;
    
    public class SampleWebSocket extends Verticle {
    
      public void start() {
        vertx.createHttpServer().websocketHandler(new Handler<ServerWebSocket>() {
          public void handle(final ServerWebSocket ws) {
            if (ws.path.equals("/myapp")) {
              ws.dataHandler(new Handler<Buffer>() {
                public void handle(Buffer data) {
                  ws.writeTextFrame(data.toString()); // Echo it back
                }
              });
            } else {
              ws.reject();
            }
          }
        }).requestHandler(new Handler<HttpServerRequest>() {
          public void handle(HttpServerRequest req) {
            if (req.path.equals("/")) req.response.sendFile("ws.html"); // Serve the html
          }
        }).listen(8080);
      }
    }
    

    Scala

    SampleWebSocket.scala
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    import org.vertx.java.core.buffer.Buffer;
    import org.vertx.java.core.http.HttpServerRequest;
    import org.vertx.java.core.http.ServerWebSocket;
    import org.vertx.scala.deploy.Verticle
    import org.vertx.scala.core._
    
    class SampleWebSocket extends Verticle (
      _.getVertx().createHttpServer().websocketHandler{
         ws:ServerWebSocket => ws.path match {
            case "/myapp" => ws.dataHandler{data : Buffer =>   ws.writeTextFrame(data.toString())}
            case _ => ws.reject();
          }}
          .requestHandler{req : HttpServerRequest => req.path match {case ("/") => req.response.sendFile("ws.html")}}
          .listen(8080)
    )()
    

    II-HttpWebServer

    Vert.x allows you to easily write full featured, highly performant and scalable HTTP and HTTPS servers.

    The following example starts up an Http server, listening on port 8080, and logging all received requests.

    Java

    SampleHttpWebServer.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    import org.vertx.java.core.Handler;
    import org.vertx.java.core.http.HttpServer;
    import org.vertx.java.core.http.HttpServerRequest;
    import org.vertx.java.core.logging.Logger;
    import org.vertx.java.deploy.Verticle;
    
    
    public class SampleHttpWebServer extends Verticle {
    
        public void start() {
            HttpServer server = vertx.createHttpServer();
            final Logger log = getContainer().getLogger();
            server.requestHandler(new Handler<HttpServerRequest>() {
                public void handle(HttpServerRequest request) {
                    log.info("A request has arrived on the server!");
                }
            }).listen(8080, "localhost");
        }
    }
    

    Scala

    SampleWebServer.scala
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    import org.vertx.java.core.http. { HttpServerRequest => JHttpServerRequest}
    import org.vertx.scala.deploy.Verticle
    import org.vertx.scala.core._
    
    class SampleWebServer extends Verticle ( x =>
      x.getVertx().createHttpServer().withRequestHandler{_ : JHttpServerRequest =>
         x.info("A request has arrived on the server!")}
    .listen(8080, "localhost")
    )()
    

    III-HttpClient

    Vert.x also provides an HttpClient API, so as to interact with the server part. The following samples create and send a GET request, then log the server’s response.

    Java

    SampleHttpClient.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    import org.vertx.java.core.Handler;
    import org.vertx.java.core.http.HttpClient;
    import org.vertx.java.core.http.HttpClientRequest;
    import org.vertx.java.core.http.HttpClientResponse;
    import org.vertx.java.core.logging.Logger;
    import org.vertx.java.deploy.Verticle;
    
    
    public class SampleHttpClient extends Verticle {
    
        @Override
        public void start() throws Exception {
            HttpClient client = vertx.createHttpClient().setHost("127.0.0.1");
            final Logger log = getContainer().getLogger();
    
            HttpClientRequest request = client.post("/some-path/", new Handler<HttpClientResponse>() {
                public void handle(HttpClientResponse resp) {
                    log.info("Got a response: ");
                }
            });
    
            request.end();
        }
    }
    

    Scala

    SampleWebClient.scala
    1
    2
    3
    4
    5
    6
    7
    
    import org.vertx.scala.deploy.Verticle
    import org.vertx.scala.core._
    
    class SampleWebClient extends Verticle (v =>
       v.getVertx.createHttpClient().setHost("127.0.0.1").setPort(8080)
       .andGetNow("/") {_ => v.info("Got a response: " )}
      )()
    

    IV-EventBus

    The event bus is like a vertebral spine, it can be used to connect distributed nodes, and to support interaction between different Verticles, even written in different languages.

    Java

    SampleEventBus.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    import org.vertx.java.deploy.Verticle;
    import org.vertx.java.core.eventbus.EventBus;
    
    public class SampleEventBus extends Verticle {
       @Override
        public void start() throws Exception {
           EventBus eb = vertx.eventBus();
           eb.send("path", "ping1");
           eb.send("path", "ping2");
       }
    }
    

    Scala

    SampleEventBus.scala
    1
    2
    3
    4
    5
    6
    7
    8
    
    import org.vertx.scala.deploy.Verticle
    import org.vertx.scala.core._
    class SampleEventBus extends Verticle ( x => {
     val  point = x ! ("path")
     point >> ("ping 1")
     point >> ("ping 2")
    }
    )()
    

    Conclusion

    This article introduced the basic of Vert.x using scala language and short examples. Full Scala language support will soon, hopefully, become available.

    Stay tuned, a subsequent post will show you more about Vert.x with Scala.

    source : http://blog.zenika.com/index.php?post/2013/02/11/fun-with-scala-and-vert-x

    Comments