summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-06-15 15:10:12 -0400
committerjoe <joe@jerkface.net>2013-06-15 15:10:12 -0400
commit28b4425f8392adeeab3978672ea615eb41eed59a (patch)
tree2a4175ff394ce1f85ac3fa8910b3fb33c36cb94f
parent3fdaa99ca55942c8747c7226ea1a1bfb7d28deda (diff)
simple chat example program.
-rw-r--r--simplechat.hs64
1 files changed, 64 insertions, 0 deletions
diff --git a/simplechat.hs b/simplechat.hs
new file mode 100644
index 00000000..a763a982
--- /dev/null
+++ b/simplechat.hs
@@ -0,0 +1,64 @@
1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3
4import Data.HList.TypeEqGeneric1()
5import Data.HList.TypeCastGeneric1()
6import ByteStringOperators
7
8import Server
9import Data.ByteString.Lazy.Char8 as L
10 ( ByteString
11 , hPutStrLn
12 , init )
13import System.IO
14 ( Handle
15 )
16import Control.Concurrent (forkIO)
17import Control.Concurrent.Chan
18import Data.HList
19
20
21startCon st = do
22 let chan = hOccursFst st
23 nr = hOccursFst st :: ConnId
24 hdl = hOccursFst st :: Handle
25 quit = writeChan chan (nr,Nothing)
26 broadcast msg = writeChan chan (nr,Just msg)
27 chan' <- dupChan chan
28 reader <- forkIO $ fix $ \loop -> do
29 (nr', line) <- readChan chan'
30 case ( line, nr==nr') of
31 ( Nothing , True ) -> Prelude.putStrLn "quit-client."
32 ( Just msg , False ) -> hPutStrLn hdl msg >> loop
33 _ -> loop
34
35 hPutStrLn hdl "Hi, what's your name?"
36 line <- getPacket hdl
37 let name = L.init line
38 Prelude.putStrLn $ "readFst: " ++ show line
39 hPutStrLn hdl ("Welcome, " <++> name <++> "!")
40 broadcast ("--> " <++> name <++> " entered.")
41
42 return (name .*. ConnectionFinalizer quit .*. st)
43
44doCon st bs cont = do
45 let hdl = hOccursFst st :: Handle
46 nr = hOccursFst st :: ConnId
47 chan = hOccursFst st
48 broadcast msg = writeChan chan (nr,Just msg)
49 name = hHead st
50 Prelude.putStrLn $ "read: " ++ show bs
51 case bs of
52 "quit\n" -> hPutStrLn hdl "Bye!"
53 _ -> do
54 broadcast (name <++> ": " <++> L.init bs)
55 cont ()
56
57
58main = do
59 (chan :: Chan (ConnId, Maybe ByteString)) <- newChan
60 doServer (5222 .*. chan .*. HNil)
61 doCon
62 startCon
63
64