【问题标题】:How to implement server-push over websocket in suave?如何在 suave 中通过 websocket 实现服务器推送?
【发布时间】:2016-01-06 23:04:07
【问题描述】:

我可以这样写吗

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 个单独的套接字循环来进行并发读写吗?

【问题讨论】:

    标签: websocket f# suave


    【解决方案1】:

    我认为您可以使用 Async.Choose 解决这个问题(有很多实现 - 虽然我不确定最规范的实现在哪里)。

    也就是说,您当然可以创建两个循环 - 在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
                | _ -> () }
    

    【讨论】:

    • 您能否为这种情况推荐一个好的 Async.Choose-implementation ?还有关于循环:this 好吗?谢谢!
    • 我认为您的双循环实现存在线程安全问题(从 2 个线程写入)
    【解决方案2】:

    没有正确的 Async.Choose 实现(至少在这种情况下),所以我们需要两个异步循环来进行并发读写;详情请见this

    【讨论】:

      猜你喜欢
      • 2013-07-26
      • 2011-07-14
      • 2010-11-28
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      相关资源
      最近更新 更多