пример web-сокета в haskell - PullRequest
0 голосов
/ 14 марта 2012
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) Зачем использовать «навсегда a = делать a; навсегда a», когда есть «forkIO (listenLoop h)»? Я читаю его как вечно начинающий разветвлять новый listenLoop для 1 входящего соединения?Другими словами, начинать разветвлять новые процессы, пока мой компьютер не выйдет из строя?Если бы был вечный цикл, я ожидаю, что он будет где-то в главном?

2) - - - и * * * есть некоторые еще не реализованные RFC вещи, которые я не смог найти в интернете, есть ли haskellаккумуляторы для этого?

ref: http://www.fatvat.co.uk/2010/01/web-sockets-and-haskell.html

Ответы [ 2 ]

2 голосов
/ 07 августа 2013

Есть причина, по которой люди могут писать такой код на Хаскеле.Haskell использует «зеленый поток», когда вы вызываете функцию forkIO, эти потоки обычно работают в одном потоке, пока у них нет причины блокировать, и в этом случае они, скорее всего, будут использовать какой-то механизм объединения потоков для получения потока, который нужно заблокироватьна.Эта функция плюс монада транзакций состояния делает тупо легким проектирование параллельных приложений на Haskell.

Если вы хотите использовать потоки ОС, есть функция forkOS.

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html

Дополнительномодуль Network.Socket для GHC использует неблокирующие функции ввода-вывода, когда это возможно, все это скрыто от пользователя.

2 голосов
/ 14 марта 2012

Предположительно accept - это вызов функции блокировки, поэтому использование forever - это не бомба.Что касается того, почему вы это делаете, я думаю, что это довольно стандартная практика для программы, которая прослушивает сокет, чтобы принимать столько соединений, сколько требуется от него.

Я не уверен на 100%, есть ли«Аккумуляторы Haskell» для точно отсутствующих частей вашего кода, но на Hackage определенно есть несколько пакетов с websocket в их названии или описании;Вы должны проверить их, а затем опубликовать более конкретный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...