2016-07-14 10 views
6

私はpurescript-halogenをウェブソケットと組み合わせて使用​​しようとしていますが、何度か試してみると一緒に使えません。PureScriptハロゲンとウェブソケット

私はthis question on Thermite and websocketsと、Driver機能に関するPhilの答えを見ました。ハロゲンもまたDriverの機能を持っていますが、エフェクトを使用するのに対してpurescript-websockets-simpleエフェクトを使用してAffエフェクトを使用してDriver機能を実行する必要があります。

websocketパッケージの同期コールバックをAffモナドで実行されている非同期コードに変換する方法はわかりません。 AVarを使用する必要がありますか? purescript-coroutines-affが必要ですか?もしそうなら、どのようにこれらの部品を一緒につなぎますか?

正しい方向のポインタを事前におねがいします。

答えて

9

この場合、確かにpurescript-aff-coroutinesを使用します。

  1. ハロー
  2. module Main where 
    
    import Prelude 
    
    import Control.Coroutine (Producer, Consumer, consumer, runProcess, ($$)) 
    import Control.Coroutine.Aff (produce) 
    import Control.Monad.Aff (Aff) 
    import Control.Monad.Aff.AVar (AVAR) 
    import Control.Monad.Eff (Eff) 
    import Control.Monad.Eff.Exception (EXCEPTION) 
    import Control.Monad.Eff.Var (($=)) 
    
    import Data.Array as Array 
    import Data.Either (Either(..)) 
    import Data.Maybe (Maybe(..)) 
    
    import Halogen as H 
    import Halogen.HTML.Indexed as HH 
    import Halogen.Util (runHalogenAff, awaitBody) 
    
    import WebSocket (WEBSOCKET, Connection(..), Message(..), URL(..), runMessageEvent, runMessage, newWebSocket) 
    
    ---------------------------------------------------------------------------- 
    -- Halogen component. This just displays a list of messages and has a query 
    -- to accept new messages. 
    ---------------------------------------------------------------------------- 
    
    type State = { messages :: Array String } 
    
    initialState :: State 
    initialState = { messages: [] } 
    
    data Query a = AddMessage String a 
    
    ui :: forall g. H.Component State Query g 
    ui = H.component { render, eval } 
        where 
        render :: State -> H.ComponentHTML Query 
        render state = 
        HH.ol_ $ map (\msg -> HH.li_ [ HH.text msg ]) state.messages 
    
        eval :: Query ~> H.ComponentDSL State Query g 
        eval (AddMessage msg next) = do 
        H.modify \st -> { messages: st.messages `Array.snoc` msg } 
        pure next 
    
    ---------------------------------------------------------------------------- 
    -- Websocket coroutine producer. This uses `purescript-aff-coroutines` to 
    -- create a producer of messages from a websocket. 
    ---------------------------------------------------------------------------- 
    
    wsProducer :: forall eff. Producer String (Aff (avar :: AVAR, err :: EXCEPTION, ws :: WEBSOCKET | eff)) Unit 
    wsProducer = produce \emit -> do 
        Connection socket <- newWebSocket (URL "ws://echo.websocket.org") [] 
    
        -- This part is probably unnecessary in the real world, but it gives us 
        -- some messages to consume when using the echo service 
        socket.onopen $= \event -> do 
        socket.send (Message "hello") 
        socket.send (Message "something") 
        socket.send (Message "goodbye") 
    
        socket.onmessage $= \event -> do 
        emit $ Left $ runMessage (runMessageEvent event) 
    
    ---------------------------------------------------------------------------- 
    -- Coroutine consumer. This accepts a Halogen driver function and sends 
    -- `AddMessage` queries in when the coroutine consumes an input. 
    ---------------------------------------------------------------------------- 
    
    wsConsumer 
        :: forall eff 
        . (Query ~> Aff (H.HalogenEffects (ws :: WEBSOCKET | eff))) 
        -> Consumer String (Aff (H.HalogenEffects (ws :: WEBSOCKET | eff))) Unit 
    wsConsumer driver = consumer \msg -> do 
        driver $ H.action $ AddMessage msg 
        pure Nothing 
    
    ---------------------------------------------------------------------------- 
    -- Normal Halogen-style `main`, the only addition is a use of `runProcess` 
    -- to connect the producer and consumer and start sending messages to the 
    -- Halogen component. 
    ---------------------------------------------------------------------------- 
    
    main :: forall eff. Eff (H.HalogenEffects (ws :: WEBSOCKET | eff)) Unit 
    main = runHalogenAff do 
        body <- awaitBody 
        driver <- H.runUI ui initialState body 
        runProcess (wsProducer $$ wsConsumer driver) 
        pure unit 
    

    これはあなたにほとんどすぐに印刷しページを与える必要があります:それはあなたが、ドライバにメッセージをプッシュConsumerにフックすることができますコルーチンProducerを取得します

  3. 何か
  4. さよなら

しかし、それは今までやっていますあなたが必要なもの、正直! 「本当の」ソースを持つプロデューサーを使用すると、必要なものにもっと似たものが得られます。

関連する問題