9

can I write something like this

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
    }

or do I need 2 seperate socket-loop for concurrent read-write?

Viet NT
  • 305
  • 2
  • 9

2 Answers2

9

I think you could solve this using Async.Choose (there is a bunch of implementations - though I'm not sure where is the most canonical one).

That said, you can certainly create two loops - the reading one inside socket { .. } so that you can receive data from web sockets; the writing one can be ordinary async { ... } block.

Something like this should do the trick:

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
            | _ -> () }
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • could you please suggest a good Async.Choose-implementation for this case? and about too loop: is [this](https://github.com/SuaveIO/suave/issues/307#issuecomment-146873334) good? thank! – Viet NT Oct 09 '15 at 14:58
  • 1
    I think your implementation of two-loop have thread-safe problem (write from 2 threads) – Viet NT Oct 09 '15 at 15:06
2

There isn't a proper implementation of Async.Choose (for this case at least), so we need two async-loop for concurrent read-write; see this for more detail

Viet NT
  • 305
  • 2
  • 9