Implementing a Chat Server in Ruby
Me and Uncool participated in a ‘Linux Challenge’ recently in one of the IT Fest of the University of Delhi.
Although we just managed a Third Prize by some Python heroics in the end by Uncool, we were behind the First team only by a single problem of implementing a chat program using Unix Pipes. We had little clue about UNIX Pipes so we thought about implementing it by using standard libraries from either Ruby or Python, as they (event organizers) said they would still consider it. Expectedly, they didn’t have any trace of Ruby on their machines which were running Fedora 9.
Uncool was unsuccessful in implementing it in Python, the documentation was ugly enough.
Reasonably angry, I decided to prove myself why we could have at least won the Second prize without even a drop of sweat.
TCPSocket and TCPServer classes in the Ruby Standard Library are braindead-simple to implement.
The Ruby Programming Language shows how (comments are self-explanatory) :
# A Multithreaded Server require 'socket' # This method expects a socket connected to a client. # It reads lines from the client, reverses them and sends them back. # Multiple threads may run this method at the same time. def handle_client(c) while true input = c.gets.chop # Read a line of input from the client break if !input # Exit if no more input break if input == "quit" # or if the client asks to. c.puts(input.reverse) # Otherwise, respond to client. c.flush # Force our output out end c.close # Close the client socket end server = TCPServer.open(2000) # Listen on port 2000 while true # Servers loop forever client = server.accept # Wait for a client to connect Thread.start(client) do |c| # Start a new thread handle_client(c) # And handle the client on that thread end end |
Gserver, one of the better standard libraries in Ruby.
More flexible than the socket library, it can be used to implement application level servers, it has a few useful predefined methods like the number of connections, event logging and handles all threading problems by itself, that means multiple users can connect on a single server at once (Asynchronous Socket programming - which is, where many clients connect to a single server and send input for processing concurrently, the server then handles all the connected clients asynchronously and process the data as and whenever it is available from any of them.)
This little toy Chat Program reads a single input from the client, shuffles it and sends it back.
CLIENT
require 'socket' # Sockets are in standard library sock = TCPSocket.open("localhost",1234) # Socket to listen on port 1234 l = STDIN.gets # Get a single input from console sock.puts(l) # Send input to the server sock.flush # Force input line = sock.readpartial(4096) # Read server's response puts line # Display the response to the user sock.close # Close the socket |
SERVER
require 'gserver' # Algorithm to shuffle a string def shuffle(str) lenth = str.length index = (lenth-1) while(index >= 0) do random_number = rand(lenth) str[random_number], str[index] = str[index], str[random_number] index = index - 1 end str end class Server < GServer # Server class derived from GServer super class def initialize(port=1234, *args) # to use the initialize function super(port, *args) end def serve(io) # Serve method handles connections input = io.gets.chop! # Get input from client console io.puts(shuffle(input)) # Return the shuffled input onto the client console puts input # Print the client message end end server = Server.new while (input = gets) # Loop server while user gives an input if input =~ /start/ server.start # Start the server if the user types "init" end if input =~ /shutdown/ server.shutdown # Shut the server down if the user types "shutdown" break end end |
Thin provides a TCPServer Socket backend which can also be used for similar purposes. Its pretty much the same except that it uses the EventMachine library for the Network I/O.

