<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nine Mohs &#187; Programming</title>
	<atom:link href="http://code.scrapcrap.org/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://code.scrapcrap.org</link>
	<description>Ruby, Programming, Technology, Fun</description>
	<lastBuildDate>Sun, 07 Feb 2010 11:19:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Implementing a Chat Server in Ruby</title>
		<link>http://code.scrapcrap.org/implementing-a-chat-server-in-ruby</link>
		<comments>http://code.scrapcrap.org/implementing-a-chat-server-in-ruby#comments</comments>
		<pubDate>Tue, 13 Jan 2009 19:26:17 +0000</pubDate>
		<dc:creator>kitallis</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Chat Server]]></category>
		<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sockets]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[Thin]]></category>

		<guid isPermaLink="false">http://code.scrapcrap.org/?p=87</guid>
		<description><![CDATA[Me and Uncool participated in a &#8216;Linux Challenge&#8217; 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 [...]]]></description>
			<content:encoded><![CDATA[<p>Me and <a href="http://uncool.in/">Uncool</a> participated in a &#8216;Linux Challenge&#8217; recently in one of the IT Fest of the <a href="http://en.wikipedia.org/wiki/Nsit">University of Delhi</a>.<br />
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&#8217;t have any trace of Ruby on their machines which were running Fedora 9.<br />
Uncool was unsuccessful in implementing it in Python, the documentation was ugly enough.<br />
Reasonably angry, I decided to prove myself why we could have at least won the Second prize without even a drop of sweat.</p>
<p>TCPSocket and TCPServer classes in the Ruby Standard Library are braindead-simple to implement.<br />
<a href="http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177">The Ruby Programming Language</a> shows how (comments are self-explanatory) :</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p87code4'); return false;">View Code</a> RUBY</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p874"><td class="code" id="p87code4"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># A Multithreaded Server</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'socket'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># This method expects a socket connected to a client.</span>
<span style="color:#008000; font-style:italic;"># It reads lines from the client, reverses them and sends them back.</span>
<span style="color:#008000; font-style:italic;"># Multiple threads may run this method at the same time.</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> handle_client<span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#0000FF; font-weight:bold;">true</span>
   input = c.<span style="color:#CC0066; font-weight:bold;">gets</span>.<span style="color:#CC0066; font-weight:bold;">chop</span>                 <span style="color:#008000; font-style:italic;"># Read a line of input from the client</span>
   <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> !input                     <span style="color:#008000; font-style:italic;"># Exit if no more input</span>
   <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> input == <span style="color:#996600;">&quot;quit&quot;</span>            <span style="color:#008000; font-style:italic;"># or if the client asks to.</span>
   c.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>input.<span style="color:#9900CC;">reverse</span><span style="color:#006600; font-weight:bold;">&#41;</span>               <span style="color:#008000; font-style:italic;"># Otherwise, respond to client.</span>
   c.<span style="color:#9900CC;">flush</span>                             <span style="color:#008000; font-style:italic;"># Force our output out</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
 c.<span style="color:#9900CC;">close</span>                               <span style="color:#008000; font-style:italic;"># Close the client socket</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
server = TCPServer.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2000</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># Listen on port 2000</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#0000FF; font-weight:bold;">true</span>                             <span style="color:#008000; font-style:italic;"># Servers loop forever</span>
 client = server.<span style="color:#9900CC;">accept</span>                <span style="color:#008000; font-style:italic;"># Wait for a client to connect</span>
 <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span>client<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>           <span style="color:#008000; font-style:italic;"># Start a new thread</span>
   handle_client<span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#41;</span>                    <span style="color:#008000; font-style:italic;"># And handle the client on that thread</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><a href="http://ruby-doc.org/stdlib/libdoc/gserver/rdoc/classes/GServer.html#M000820">Gserver</a>, one of the better standard libraries in Ruby.</p>
<p>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.)</p>
<p>This little toy Chat Program reads a single input from the client, <a href="http://code.scrapcrap.org/?p=44">shuffles</a> it and sends it back.</p>
<p><strong>CLIENT</strong></p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p87code5'); return false;">View Code</a> RUBY</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p875"><td class="code" id="p87code5"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'socket'</span>                           <span style="color:#008000; font-style:italic;"># Sockets are in standard library</span>
&nbsp;
sock = TCPSocket.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;localhost&quot;</span>,<span style="color:#006666;">1234</span><span style="color:#006600; font-weight:bold;">&#41;</span>    <span style="color:#008000; font-style:italic;"># Socket to listen on port 1234</span>
&nbsp;
  l = STDIN.<span style="color:#CC0066; font-weight:bold;">gets</span>                           <span style="color:#008000; font-style:italic;"># Get a single input from console</span>
  sock.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>l<span style="color:#006600; font-weight:bold;">&#41;</span>                             <span style="color:#008000; font-style:italic;"># Send input to the server</span>
  sock.<span style="color:#9900CC;">flush</span>                               <span style="color:#008000; font-style:italic;"># Force input</span>
  line = sock.<span style="color:#9900CC;">readpartial</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">4096</span><span style="color:#006600; font-weight:bold;">&#41;</span>            <span style="color:#008000; font-style:italic;"># Read server's response</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> line                                <span style="color:#008000; font-style:italic;"># Display the response to the user</span>
&nbsp;
sock.<span style="color:#9900CC;">close</span>                                 <span style="color:#008000; font-style:italic;"># Close the socket</span></pre></td></tr></table></div>

<p><strong>SERVER</strong></p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p87code6'); return false;">View Code</a> RUBY</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p876"><td class="code" id="p87code6"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'gserver'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Algorithm to shuffle a string</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> shuffle<span style="color:#006600; font-weight:bold;">&#40;</span>str<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
lenth = str.<span style="color:#9900CC;">length</span>
&nbsp;
index = <span style="color:#006600; font-weight:bold;">&#40;</span>lenth<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">while</span><span style="color:#006600; font-weight:bold;">&#40;</span>index <span style="color:#006600; font-weight:bold;">&amp;</span>gt;= <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
   random_number = <span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>lenth<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
   str<span style="color:#006600; font-weight:bold;">&#91;</span>random_number<span style="color:#006600; font-weight:bold;">&#93;</span>, str<span style="color:#006600; font-weight:bold;">&#91;</span>index<span style="color:#006600; font-weight:bold;">&#93;</span> = str<span style="color:#006600; font-weight:bold;">&#91;</span>index<span style="color:#006600; font-weight:bold;">&#93;</span>, str<span style="color:#006600; font-weight:bold;">&#91;</span>random_number<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
   index = index <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
str
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Server <span style="color:#006600; font-weight:bold;">&amp;</span>lt; GServer                  <span style="color:#008000; font-style:italic;"># Server class derived from GServer super class</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>port=<span style="color:#006666;">1234</span>, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>      <span style="color:#008000; font-style:italic;"># to use the initialize function</span>
      <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>port, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> serve<span style="color:#006600; font-weight:bold;">&#40;</span>io<span style="color:#006600; font-weight:bold;">&#41;</span>                         <span style="color:#008000; font-style:italic;"># Serve method handles connections</span>
&nbsp;
      input = io.<span style="color:#CC0066; font-weight:bold;">gets</span>.<span style="color:#CC0066; font-weight:bold;">chop!</span>             <span style="color:#008000; font-style:italic;"># Get input from client console</span>
      io.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>shuffle<span style="color:#006600; font-weight:bold;">&#40;</span>input<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>           <span style="color:#008000; font-style:italic;"># Return the shuffled input onto the client console</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> input                        <span style="color:#008000; font-style:italic;"># Print the client message </span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
server = Server.<span style="color:#9900CC;">new</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span>input = <span style="color:#CC0066; font-weight:bold;">gets</span><span style="color:#006600; font-weight:bold;">&#41;</span>                     <span style="color:#008000; font-style:italic;"># Loop server while user gives an input</span>
&nbsp;
 <span style="color:#9966CC; font-weight:bold;">if</span> input =~ <span style="color:#006600; font-weight:bold;">/</span>start<span style="color:#006600; font-weight:bold;">/</span>
   server.<span style="color:#9900CC;">start</span>                          <span style="color:#008000; font-style:italic;"># Start the server if the user types &quot;init&quot;</span>
&nbsp;
 <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
 <span style="color:#9966CC; font-weight:bold;">if</span> input =~ <span style="color:#006600; font-weight:bold;">/</span>shutdown<span style="color:#006600; font-weight:bold;">/</span>
   server.<span style="color:#9900CC;">shutdown</span>                       <span style="color:#008000; font-style:italic;"># Shut the server down if the user types &quot;shutdown&quot;</span>
&nbsp;
 <span style="color:#9966CC; font-weight:bold;">break</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><a href="http://code.macournoyer.com/thin/">Thin</a> provides a <a href="http://code.macournoyer.com/thin/doc/classes/Thin/Backends/TcpServer.html">TCPServer</a> Socket backend which can also be used for similar purposes. Its pretty much the same except that it uses the <a href="http://rubyeventmachine.com/">EventMachine</a> library for the Network I/O.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.scrapcrap.org/implementing-a-chat-server-in-ruby/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

