Aimred Developer Blog January 2010 Archive

Cape Town Ruby Brigade Meeting - 20th January 2009

Topic: Microformats by Andy Volk
Venue: Sudoroom, Bandwidth Barn, 5th Floor 125 Buitengracht, Cape Town
Date: Wednesday, 20th January 2009
Time: 19:00

RSVP @ Cape Town Ruby Brigade Google Group

Rediscovering Ruby: GServer

One of the great aspects in working with Ruby is not just the language itself but the builtin APIs that come with it. In this series of Rediscovering Ruby articles I will be digging through the Core and Standard Ruby APIs looking for those useful gems that are either undiscovered or that have been forgotten over time. First up GServer, a micro-framework allowing you to quickly create servers that can handle multiple client requests.

Introduction

When people think of client-server computing with Ruby they usually default to one of the pre-existing web frameworks, most notably Rails. Oftentimes the work required to get that framework up and running, along with the required webserver and other dependencies, can be more hassle than it’s worth for a very simple server that does not need to be accessed via HTTP. Enter GServer. It comes bundled in the Ruby standard library so there are no dependencies besides the Ruby environment.

An Echo Server

To illustrate how easy it is to get up and running with GServer let’s create a simple echo server which reads in input a line at a time and sends the same input straight back.

To make use of GServer all you need to do is subclass GServer and then implement the serve method which receives a single object, a TCPSocket.

The following code listing is a simple echo server that will read in input a line at a time and echo it back:

 1 require 'gserver'
 2 class EchoServer < GServer
 3   def serve( io )
 4     loop do
 5       line = io.readline
 6       io.puts( line )
 7     end
 8   end
 9  end
10  echo_server = EchoServer.new( 5179 )
11  echo_server.audit = true # Turn logging on
12  echo_server.start        # Start server
13  echo_server.join         # Prevent exiting while server is running

We can then connect to the echo server using a TCPSocket.

1 >> require 'socket'
2 >> echo = TCPSocket.open( 'localhost', 5179 )
3 >> echo.puts( "Hello\nWorld" )
4 >> puts( echo.readline )
5 => "Hello"
6 >> puts( echo.readline )
7 => "World"

Notice that we sent one string but ( “Hello\nWorld” ) because we are using readline it is split in two due to the newline character (“\n”).

Controlling the Server

As illustrated in the code listing above start will start the server, which can then be queried with

1 echo_server.stopped?
2 EchoServer.in_service?( 5179 )

To stop the server there are three methods

1 echo_server.stop
2 EchoServer.stop( 5179 )
3 echo_server.shutdown

The stop methods will stop the server immediately closing any open connections, while shutdown will wait for any open connections to close before gracefully shutting down the server.

Multiple Servers

GServer also allows you to run multiple services (using different port numbers) from the same Ruby script which can be stopped and started individually.

1 echo_server_1 = EchoServer.new( 'localhost', 5179 )
2 echo_server_2 = EchoServer.new( 'localhost', 5180 )
3 echo_server_1.start
4 echo_server_2.start
5 echo_server_1.shutdown
6 EchoServer.stop( 5180 )

Logging

Only the serve method is required to be implemented, however there are a number of hook methods that can be implemented to execute code at a certain events which may be useful for functionality like custom logging.

  • starting – Server starts up
  • connecting( tcp_socket ) – Before serve
  • disconnecting( client_port ) – After serve
  • stopping – Server shuts down

Note that these methods are only called if the audit attribute is set to true before start is called (see line 11 in the first code listing above). It’s even possible to entirely replace GServer’s logging with your own by also implementing:

  • log( message )
  • error( exception )

Exception Handling

GServer will handle all exceptions raised in the serve method, making sure the connection is closed properly and keeping the server up and running, ready to serve the next request.

About Aimred

Aimred is a specialist Ruby and Ruby on Rails development house and consultancy based in Cape Town, South Africa.

We provide Ruby and Ruby on Rails development, consulting and training services to businesses and organisations of all sizes. If you want to find out how we can help you, contact us at info@aimred.com.