2015-10-09 72 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个线程写入) –

相关问题