diff options
author | joe <joe@jerkface.net> | 2013-06-15 15:10:12 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-06-15 15:10:12 -0400 |
commit | 28b4425f8392adeeab3978672ea615eb41eed59a (patch) | |
tree | 2a4175ff394ce1f85ac3fa8910b3fb33c36cb94f | |
parent | 3fdaa99ca55942c8747c7226ea1a1bfb7d28deda (diff) |
simple chat example program.
-rw-r--r-- | simplechat.hs | 64 |
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 | |||
4 | import Data.HList.TypeEqGeneric1() | ||
5 | import Data.HList.TypeCastGeneric1() | ||
6 | import ByteStringOperators | ||
7 | |||
8 | import Server | ||
9 | import Data.ByteString.Lazy.Char8 as L | ||
10 | ( ByteString | ||
11 | , hPutStrLn | ||
12 | , init ) | ||
13 | import System.IO | ||
14 | ( Handle | ||
15 | ) | ||
16 | import Control.Concurrent (forkIO) | ||
17 | import Control.Concurrent.Chan | ||
18 | import Data.HList | ||
19 | |||
20 | |||
21 | startCon 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 | |||
44 | doCon 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 | |||
58 | main = do | ||
59 | (chan :: Chan (ConnId, Maybe ByteString)) <- newChan | ||
60 | doServer (5222 .*. chan .*. HNil) | ||
61 | doCon | ||
62 | startCon | ||
63 | |||
64 | |||