title: Game server in Haskell
body: <p>I'm using <code>Network</code> and <code>Gloss</code> for a game server in Haskell. It works fine, except that the client has to close for the server to receive the data it sent. I bet it's a case of laziness...</p>
  
  <p>Minimalist server:</p>
  
  <pre><code>import Network
  import System.IO
  
  main = do
      sock &lt;- listenOn (PortNumber (fromIntegral 12345))
      loop sock
  
  loop sock = do
      (hIn, _, _) &lt;- accept sock
      str &lt;- hGetContents hIn
      print str
      loop sock
  </code></pre>
  
  <p>Minimalist client:</p>
  
  <pre><code>import Network
  import System.IO
  import Graphics.Gloss.Interface.IO.Game
  
  main = playIO
      (InWindow "Test Multi" (500, 500) (500, 500))
      white
      60
      Nothing
      draw
      (\_ x -&gt; return x)
      advance
  
  draw Nothing = return blank
  draw (Just x) = return (Text (show x))
  
  advance _ Nothing = do
      hOut &lt;- connectTo "000.000.0.0" (PortNumber (fromIntegral 12345))
      hSetBuffering hOut NoBuffering
      hPutStr hOut "Hello!"
      return (Just hOut)
  advance _ x = return x
  </code></pre>
  
  <p>I start the server, wait 10 seconds, then start the client, wait 15 seconds, see that nothing happens on the server, closes the client, see "Hello!" suddenly appear on the server.
  I would like "Hello!" to appear while the client is running, in an <code>advance</code> call, otherwise I can't make a multiplayer game (sob)!</p>
  
  <hr>
  
  <p>However, if I change the client's code to</p>
  
  <pre><code>main = loop Nothing
  loop x = do
      x' &lt;- advance 0 x
      getLine
  </code></pre>
  
  <p>the sever immediatly shows "Hello!" while the client is waiting for my input.</p>
  
  <hr>
  
  <p>I tried, as suggested in another question, to use bang patterns and <code>hClose</code>:</p>
  
  <pre><code>-- ...
  !str &lt;- hGetContents hIn
  hClose hIn
  -- ...
  </code></pre>
  
  <p>which makes the output appear immediatly, without the client closing. That's great. But, I plan to use bytestrings because the data I send to the server is serialized, so I <code>import qualified Data.ByteString as B</code> and change <code>hGetContents</code> to <code>B.hGetContents</code>, which makes the problem re-appear.</p>
  
  <hr>
  
  <p>The problem was indeed a case of laziness. <code>hGetContents</code> reads lazily all the contents of the <code>Handle</code>, so it finishes only when it's closed, when the client aborts the connection. Instead, I used <code>hGetLine</code> that returns the content each time it encounters a <code>\n</code>, which I use as a <code>end-of-message</code> tag.</p>