Firstly, define a Verticle

A verticle is defined as a “package of code that Vert.x executes” and due to Vert.x polyglot design, can be written in a number of languages such as Java, JavaScript, CoffeeScript, Ruby, Python or Groovy with the ability to mix and match several languages in a single application. For the purposes of this post, we’ll define a simple Verticle that handles HTTP Requests to the application.

class GrailsVerticle extends Verticle { 
    public GrailsVerticle() {
        vertx.createHttpServer()
            .websocketHandler(
                new Handler<HttpServerRequest>() {
                    public void handle(HttpServerRequest req) {
                        String path = req.path().equals("/") ? "index.html" : req.path();
                        req.response().sendFile(httpFilePath + path);
                    }
                })
            .listen(8000, "127.0.0.1");
    }
}

This simple Verticle will act as a basic HTTP file server, serving files at the requested path and when no path element is provided in the request URI, will serve the index.html file. Save this file to your Grails application in grails-app/src/vertx/GrailsVerticle.java

Loading Vert.x dependencies into Grails with Maven2

As the Vert.x dependencies have now been moved to many of the Maven2 repositories, you can pull them in Grails by modifying your BuildConfig.groovy to have the data I have specified.

grails.project.target.level = 1.7
grails.project.source.level = 1.7
grails.project.dependency.resolver = "maven"
grails.project.dependency.resolution = {
    repositories {
        mavenRepo "http://central.maven.org/maven2/"
    }

    dependencies {
        compile "io.vertx:vertx-platform:2.1"
    }
}

Executing the Verticle

The Verticle can be loaded by using the PlatformLocator factory. In my setup, I only have Vert.x available in Grails while my environment is set to development. Using the provided code inside BootStrap.groovy you will be able to execute the Verticle. View code.

import grails.util.Environment
import org.vertx.java.platform.PlatformLocatorc
class BootStrap {
 
    def init = { servletContext ->
        Environment.executeForCurrentEnvironment {
            development {
                PlatformLocator.factory.createPlatformManager()
                    .deployVerticle(
                        'GrailsVerticle.java', 
                        null, 
                        [new File('./src/java/vertx').toURI().toURL()], 
                        1, 
                        null, 
                        null)
            }
        }
    }
}

You will be able to easily reference any code that is inside your Grails application inside your Vert.x application. This has made development significantly faster for me. Modifications to code inside your Vert.x application will be compiled as you make changes, allowing for you to save time starting/stopping the Vert.x platform.

Some things to keep in mind…

I have used this approach as I have two servers handling clearly defined jobs, a Vert.x application server handing lower latency game logic, and a Grails server handling any data (such as player information, maps and settings files). We can think of the Grails application as the service managing all of my data, while the Vert.x application handles data processing.

In a production environment, the Vert.x code would be launched separately, and communicating with the Grails application via a RESTful service. This allows you to take advantage of the juicy clustering features of Vert.x.

For your rapid development phase, this is also great for taking advantage of Grails automatic re-compilation of changes (spring loaded). Spring Loaded transforms classes as loadtime to make amenable for later reloading; this worked out-of-the-box. Happy days.

I have taken this approach due to there being a higher ratio of Vert.x application servers to Grails servers. The Grails servers will manage the Vert.x clusters, remotely spawning and killing them as the number of players increases, and decreases.

Additionally, from a security point of view as the Grails servers will be handling all sensitive data, only game data needs to be passed to the Vert.x application servers (which is generally insensitive). This means that we can ensure the game stay open source, with a secure by design implementation.