2013-05-08 16 views
5

liftIOの逆のようなものがありますか?私はWebSocketを使用しています。サーバーからのメッセージを別のスレッドで受信できるようにしたいと考えています。IOモナド内のモナドを使用する

import Network.WebSockets 
import qualified Data.Text as T 
import Control.Monad.IO.Class 
import Control.Monad 
import Control.Concurrent 
import Control.Applicative 

printMessages :: WebSockets Hybi00() 
printMessages = forever $ do 
    resp <- receiveDataMessage 
    liftIO $ print resp 

run :: WebSockets Hybi00() 
run = do 
    liftIO . forkIO $ printMessages 
    forever $ do 
     line <- liftIO getLine 
     sendTextData . T.pack $ line 

main = connect "0.0.0.0" 8080 "/" run 

だからprintMessagesは、サーバーからのメッセージをリッスンし、それらをプリントアウトし続け:ここで私がやっているものです。問題は、forkIOは、IO()を返す関数を期待しているということです。 IOモナドにprintMessagesを実行する方法はありますか?

+1

[ 'runWithSocket'](http://hackage.haskell.org/packages/archive/websockets/latest/doc/html/ Network-WebSockets.html#v:runWithSocket)おそらく?一般的に、 'MonadIO m'から' IO'を得るためには、 'runXY'関数が必要です。 –

答えて

5

私がこの権利を理解している場合、別のスレッドでメッセージを受け取る理由は、メインスレッドがユーザーの入力を待つためです。

the documentationを見てみると、スレッドの役割を元に戻すと、メインスレッドで受信し、もう一方から非同期で送信する方が楽になるようです。

次に、あなたはあなたがモナドを混合全体の問題を回避、IOに住んでいるsendSink :: Sink p -> Message p -> IO()で使用できる、フォークの前にシンクをつかむためにgetSink :: Protocol p => WebSockets p (Sink p)を使用することができます。言い換えれば

、このような何かにあなたのコードを再構築:

sendMessages :: Sink Hybi00 -> IO() 
sendMessages sink = forever $ do 
    line <- getLine 
    let msg = textData . T.pack $ line 
    sendSink sink msg 

run :: WebSockets Hybi00() 
run = do 
    sink <- getSink 
    liftIO . forkIO $ sendMessages sink 
    forever $ do 
     resp <- receiveDataMessage 
     liftIO $ print resp 

main = connect "0.0.0.0" 8080 "/" run 
+1

ありがとう!あなたの答えを変更して私の作業コードを追加しました。 –

関連する問題