import Network
import System.IO
import Control.Concurrent
import Control.Monad(when)
import Char
serverHandshake :: String
serverHandshake =
"HTTP/1.1 101 Switching Protocols\r\n\
\Upgrade: WebSocket\r\n\
\Connection: Upgrade\r\n\
\Sec-WebSocket-Accept: *******************\r\n\r\n"
acceptLoop socket = forever $ do
(h,_,_) <- accept socket
------------------------
hPutStr h serverHandshake
hSetBuffering h NoBuffering
forkIO (listenLoop h)
where
forever a = do a; forever a
main = withSocketsDo $ do
h <- listenOn (PortNumber 8000)
acceptLoop h
sClose h
return ()
listenLoop :: Handle -> IO ()
listenLoop h = do
sendFrame h "aleloia"
msg <- readFrame h
putStrLn msg
when (msg /= "quit") (listenLoop h)
readFrame :: Handle -> IO String
readFrame h = readUntil h ""
where
readUntil h str = do
new <- hGetChar h
if new == chr 0
then readUntil h ""
else if new == chr 255
then return str
else readUntil h (str ++ [new])
sendFrame :: Handle -> String -> IO ()
sendFrame h s = do
hPutChar h (chr 0)
hPutStr h s
hPutChar h (chr 255)
1) why use “forever a = do a; forever a” when there is “forkIO (listenLoop h)”
I read it as forever start forking a new listenLoop for 1 incoming connection? In other words start forking new processes until my pc crashes? If there would be a forever loop I expect it to be in the main somewhere?
2) – – – and * * * is some not yet implemented RFC stuff I could not find on the internet, are there haskell batteries for this?
ref: http://www.fatvat.co.uk/2010/01/web-sockets-and-haskell.html
Presumably
acceptis a blocking function call, so the use offoreverisn’t a fork-bomb. As for why you do this, well, I think it’s fairly standard practice for a program that listens on a socket to accept as many connections as are requested of it.I’m not 100% sure whether there are “Haskell batteries” for exactly the missing parts of your code, but there are definitely several packages on Hackage with websocket in their name or description; you should check those out and then post a more specific question.