9

このようなことを書いてもいいですか

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 つの別個のソケットループが必要ですか?

4

2 に答える 2

9

これを使用して解決できると思いますAsync.Choose(実装がたくさんありますが、最も標準的な実装がどこにあるかはわかりません)。

とはいえ、確かに 2 つのループを作成できます。1 つは内部の読み取りでsocket { .. }、Web ソケットからデータを受信できます。書き込みは通常の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
            | _ -> () }
于 2015-10-09T14:10:21.187 に答える
2

(少なくともこの場合は) Async.Choose の適切な実装がないため、同時読み取り/書き込みには 2 つの非同期ループが必要です。詳しくはこちらをご覧ください

于 2015-10-09T13:43:08.190 に答える