2016-05-17 38 views
3

我想用purescript-thermite構建一個使用websockets的應用程序。這個想法是應用程序使用websockets連接到某個服務器並實時更新HTML頁面。但是,我找不到如何將它連接到鋁熱工作流程的方法。我有一個specrenderperformAction組成。 render可以訪問dispatch函數。但是,我需要在渲染元素之前啓動websockets(我可能會將它放到main中),但是在收到消息後,我需要理想地從外部向組件發送事件dispatch。什麼是最好的方式來做到這一點?Purescript鋁熱劑和websocket

回答

4

我不確定它是不是'正確'的方式,但它的工作原理。爲了訪問websocket連接,我必須把它放入狀態。要初始化它,我把它放到componentWillMount函數中。所以初始化看起來像這樣:

type State = { 
    conn :: Maybe Connection 
} 

main :: Eff (...) Unit 
main = do 
    let rspec = T.createReactSpec spec initialState 
    let component = React.createClass $ rspec.spec {componentWillMount=mountInit rspec.dispatcher} 

mountInit :: forall props eff. 
    (ReactThis props State -> Action -> 
     Eff (... | eff) Unit) 
    -> ReactThis props State 
    -> Eff (... | eff) Unit 
mountInit dispatch this = do 
    let handlers = { 
     connected: log "Service connected" 
     , disconnected: log "Disconnected" 
     , handle: \msg -> dispatch this (WebsockMsg msg) 
    } 
    conn <- createConnection "ws://localhost:3000/websock/webclient" handlers 
    void $ transformState this (\s -> s{conn= Just conn}) 
5

期望的是您將呈現您的組件,獲取驅動程序功能的句柄,然後設置您的websocket連接並使用驅動程序功能來提供更新。

但是,如果您需要首先將WebSocket連接設置爲出於某種原因,那麼您將需要使用一些技巧,一旦安裝完成後可能需要一個Ref來保存驅動程序功能。這樣,在更新Ref之前,您需要手動驗證您是否嘗試調用驅動程序功能。

更先進的解決方案可以是包裝你WebSocket協議在協程(見purescript-coroutines)的形式,並且在類型明確地表示任何設置階段:

type Connection = 
    Aff MyEffects { initialData :: InitialData 
       , updateStream :: Producer (Aff MyEffects) UpdateMessage 
       } 

這裏,InitialData表示數據您在安裝時收到,可能會傳遞給組件,並且UpdateMessage表示來自服務器的增量更新,它將傳遞給驅動程序功能。然後你可以用main連接所有這些。

+0

有沒有這種技術的例子?謝謝! –

+0

我懂了!這個例子就是@ondra給出的例子 –