Как реализовать серверный пуш через веб-сокет в учтивом?

Могу я написать что-то вроде этого

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 (есть множество реализаций - хотя я не уверен, где самая каноническая).

Тем не менее, вы, безусловно, можете создать две петли - чтение внутри 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
            | _ -> () }

Не существует правильной реализации Async.Choose (по крайней мере, для этого случая), поэтому нам нужны два асинхронных цикла для одновременного чтения-записи; смотрите это для более подробной информации

Другие вопросы по тегам