2015-10-09 107 views
9

我可以寫這樣的事情如何通過websocket實現服務器推送?

let echo (ws: WebSocket) = 
    fun ctx -> socket { 
     let loop = ref true    
     while !loop do 
      let! message = Async.Choose (ws.read()) (inbox.Receive()) 
      match message with 
      | Choice1Of2 (wsMessage) -> 
       match wsMessage with 
       | Ping, _, _ -> do! ws.send Pong [||] true 
       | _ ->() 
      | Choice2Of2 pushMessage -> do! ws.send Text pushMessage true 
    } 

或者我需要2個獨立的插座迴路併發讀 - 寫?

回答

2

Async.Choose沒有正確的實現(至少對於這種情況),所以我們需要兩個用於併發讀寫的異步循環;看到this更多細節

9

我想你可以解決這個使用Async.Choose(有很多實現 - 雖然我不知道哪裏是最經典的)。

也就是說,你當然可以創建兩個循環 - socket { .. }內的讀取循環,以便您可以從網絡套接字接收數據;寫一個可以是普通的async { ... }塊。

像這樣的東西應該做的伎倆:

let echo (ws: WebSocket) = 
    // Loop that waits for the agent and writes to web socket 
    let notifyLoop = async { 
     while true do 
     let! msg = inbox.Receive() 
     do! ws.send Text msg } 

    // Start this using cancellation token, so that you can stop it later 
    let cts = new CancellationTokenSource() 
    Async.Start(notifyLoop, cts.Token) 

    // The loop that reads data from the web socket 
    fun ctx -> socket { 
     let loop = ref true    
     while !loop do 
      let! message = ws.read() 
      match message with 
      | Ping, _, _ -> do! ws.send Pong [||] true 
      | _ ->() } 
+0

能否請您提出一個很好Async.Choose的實現對於這種情況?並關於太循環:是[這](https://github.com/SuaveIO/suave/issues/307#issuecomment-146873334)好?謝謝! –

+1

我認爲你的雙循環實現有線程安全問題(從2個線程寫入) –

相關問題