Как реализовать серверный пуш через веб-сокет в учтивом?
Могу я написать что-то вроде этого
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 (по крайней мере, для этого случая), поэтому нам нужны два асинхронных цикла для одновременного чтения-записи; смотрите это для более подробной информации