December 1, 2009

Groovy Goodness: ServerSocket Scripts

One of the Groovy commandline arguments is -l to start Groovy in server listening mode. We can provide a script that is read and executed while Groovy is running. The script is read each time for a new request, so we can keep Groovy running and change the script. Next time a new client connects to the server Groovy will use the new script.

In the script we have extra properties we can use. The init property is true if the script hasn't run yet for the client connection. We can check for init to run initializing code. The property socket contains the Socket for the server. The property out is set to a PrintWriter we can use to output information back to the client. Because the name is out we can use the println() method to send text back to the client. And finally we have the property line with the contents of the input (closed by a line ending) sent to the server script. To stop the client client connection from the server script we must return the String success from our script. This will close the client connection.

// File: SimpleServer.groovy

// The code block will be executed once.
if (init) {
    meta = [:]
    // We can access the socket in our script.
    meta.host = socket.inetAddress.hostAddress

// The line contains a single line of input from the client.
// If line starts with the text OUTPUT we output all gathered meta 
// information and close the client connection.
if (line.startsWith('OUTPUT')) {
    println "Server running on $meta.host"
    println "Meta info:"
    println "----------"
    meta.each { key, value -> 
        println "$key = $value"
    return "success"  // Close client connection
} else {
    // Build meta information map.
    metaInfo = line.tokenize(":")  // Input meta information as key:value
    meta[metaInfo[0]] = metaInfo[1]

Now we can run the server with Groovy:

$ groovy -l 9010 SimpleServer.groovy
groovy is listening on port 9090

And we can test the server with telnet:

$ telnet localhost 9010
Connected to localhost
Escape character is '^]'.

Server running on
Meta info:
host =
test = true
username = mrhaki
language = Groovy

Connection closed by foreign host.