Vert.x
(groovy notes)
Verticles
// server.groovy
import static org.vertx.groovy.core.streams.Pump.createPump
vertx.createNetServer().connectHandler { socket ->
createPump(socket, socket).start()
}.listen(1234);
run with vertx run server.groovy
then telnet localhost 1234
when stop:
def vertxStop() {
println "some cleanup"
}
container and vertx object
each verticle has
container
object: deploying/undeploying, config, environment variables and loggervertx
object: access to core API, TCP, HTTP, file system access, event bus, timers etc.
// get config
def config = container.config
// config passed by -conf option
$ vertx run foo.groovy -conf myconf.json
// log
def logger = container.logger
logger.info "log something"
// environment variables
// container.env
// deploying
container.deployVerticle(main)
container.deployWorkerVerticle(foo)
container.deployModule("some.module")
// passing config
def config = [ foo: "wibble", bar: false ]
container.deployVerticle("foo.childVerticle", config)
// specifying number of instances
container.deployVerticle("Foo.groovy", 10)
// getting notice
container.deployVerticle("Foo.groovy") { asyncResult ->
if (asyncResult.succeeded) {
println "deployed, id ${asyncResult.result}"
} else {
asyncResult.cause.printStackTrace()
}
}
// undeploying
container.undeployVerticle(deploymentID)
Event Bus
messages are sent on the event bus to an address (any string, acme.games.pacman
, X
)
handler is a thing that receives messages from the bus. you register a handler at an address.
register and unregister
// set a message handler
def eb = vertx.eventBus
eb.registerHandler("test.address") { message -> println "message received ${message.body}" }
// or
def myHandler = { message -> println "message received ${message.body}" }
eb.registerHandler("test.address", myHandler) { println "registered" }
// unregister
eb.unregisterHandler("test.address", myHandler) { println "unregistered" }
publishing messages
eb.publish("test.address", "hello")
sending messages
sending a message will result in only one handler registered at the address receiving the message. this is the point to point messaging pattern. (non strict round-robin)
eb.send("test.address", "hello")
replying messages
after you send a message you want to receive a reply from the recipient (request-response pattern)
// the receiver
def myHandler = { message ->
println "received ${message.body}"
message.reply "this is a reply"
}
eb.registerHandler("test.address", myHandler)
// sender
eb.send("test.address", "this is a message") { message ->
println "reply received ${message.body}"
}
it's a good convention to communicating with JSON
eb.send("test.address", ["foo": "wibble", "bar": "eek"])
distributed event bus
to make each vert.x instance participate on the same event bus, start each vert.x instance with -cluster
Shared Data
currently only support within same vert.x instance.
shared maps
def map = vertx.sharedData.getMap("demo.mymap")
map["some-key"] = 123
// in another verticle
def map = vertx.sharedData.getMap("demo.mymap")
//...
shared sets
def set = vertx.sharedData.getMap("demo.myset") // <--- getSet ??
set << "some-value"
Buffers
creating buffer
def buff = new Buffer()
def buff = new Buffer("foo")
def buff = new Buffer("some-string", "UTF-16")
def buff = new Buffer(100000)
writing to buffer
def buff = new Buffer()
// use appendXXX methods
buff.appendInt(123).appendString("hello\n")
// or leftShift operator
buff << 123 << "hello" << "\n"
socket << buff
// random access
def buff = new Buffer()
buff.setInt(1000, 123)
buff.setBytes(0, "hello")
// or
buff[1000] = 123
buff[0] = "hello"
reading from buffer
def buff = ...
for (i in 0 ..< buff.length) {
println "byte value at $i is ${buff.getByte(i)}"
// or
println "byte value at $i is ${buff[i]}"
}
other buffer methods: length()
, copy()