@@ -1,4 +1,14 @@
1−-- A concurrent TCP server that prints everything it receives to stdout.
1+-- A concurrent TCP server that:
2+--
3+-- * receives connections from clients
4+-- * splits the incoming data into lines
5+-- * lines from concurrent connections are merged into a single srteam
6+-- * writes the line stream to an output file
7+
8+import Control.Monad.IO.Class (liftIO)
9+import Data.Char (ord, chr)
10+import System.IO (openFile, IOMode(..), hClose, hPutStrLn)
11+import System.Environment (getArgs)
212
313import Streamly
414import qualified Streamly.Fold as FL
@@ -8,15 +18,20 @@ import qualified Network.Socket as NS
818import qualified Streamly.Prelude as S
919
1020main :: IO ()
11−main = S.drain
12− $ parallely $ S.mapM (withSocket recv)
13− $ serially $ fmap fst (NS.recvConnectionsOn 8090)
21+main = do
22+ h <- openOutput
23+ S.mapM_ (hPutLines h)
24+ $ S.concatMapBy parallel (withSocket recv)
25+ $ fmap fst (NS.recvConnectionsOn 8090)
26+ hClose h
1427
1528 where
1629
17− withSocket f sk = f sk >> NS.close sk
30+ openOutput = fmap head getArgs >>= \file -> openFile file AppendMode
31+
32+ withSocket f sk = S.finally (liftIO (NS.close sk)) (f sk)
33+ hPutLines h = hPutStrLn h . map (chr . fromIntegral) . A.toList
34+ ord' = (fromIntegral . ord)
1835 recv =
19− S.mapM_ print
20− . FL.sessionsOf 3 FL.sum
21− . S.map A.length
22− . NS.readArrays
36+ FL.splitSuffixBy (== ord' '\n') (A.toArrayN 1024)
37+ . NS.read