如何在多线程场景中管理WebSocketClient ReceiveAsync?

如何在多线程场景中管理WebSocketClient ReceiveAsync?,websocket,f#,Websocket,F#,查找WebSocketClient示例时,我只发现了一个简单的示例,其中包含一个请求/响应场景 种类: 键入WSClientSimple(url)= 设ws=newclientwebsocket() 让lockConnection=Object() 让我们连接()= 锁定连接(乐趣()-> 如果不是(ws.State=WebSocketState.Open),则 ConnectAsync(Uri(url),CancellationToken.None) |>Async.AwaitTask |>A

查找WebSocketClient示例时,我只发现了一个简单的示例,其中包含一个请求/响应场景

种类:

键入WSClientSimple(url)=
设ws=newclientwebsocket()
让lockConnection=Object()
让我们连接()=
锁定连接(乐趣()->
如果不是(ws.State=WebSocketState.Open),则
ConnectAsync(Uri(url),CancellationToken.None)
|>Async.AwaitTask |>Async.RunSynchronously//await
else()
) 
让我们接收()=
锁定连接(乐趣()->
让rec readStream finalText endOfMessage=
let buffer=ArraySegment(Array.zeroCreate 1024)
让result=ws.ReceiveAsync(buffer,CancellationToken.None)|>Async.waittask |>Async.RunSynchronously
让text=finalText+Encoding.UTF8.GetString(buffer.Array |>Array.take result.Count)
如果是result.EndOfMessage,则为text
else readStream text true
readStream“”为false
)
让SendRequestJsonMessage=
let bytes=Encoding.UTF8.GetBytes(jsonMessage:string)
let ByteMessage=ArraySegment(字节,0,字节.长度)
如果不是(ws.State=WebSocketState.Open),则
连接()
//发送请求。。。
ws.SendAsync(ByteMessage,WebSocketMessageType.Text,true,CancellationToken.None)|>Async.AwaitTask |>Async.RunSynchronously
// ... 读取响应
接收()
成员this.SendRequest=SendRequest请求
显然,它与:

[]
此成员。`Receive Sequential```()=
让客户端=WSClientSimple(“url”)
因为我在1..100做
client.SendRequest“aaa”|>忽略
而且(由于orrible锁),多线程使用同一客户端:

[]
成员此。`Receive parallel on the same client``()=
让客户端=WSClientSimple(“url”)
对于1..100 do中的uu
异步{
client.SendRequest“aaa”|>忽略
}|>异步启动
现在,如果我真的想从WebSocket“双工”CPM通信中获取beast,我会继续从套接字读取数据,发送请求而不阻塞,并将接收到的消息分发给正确的调用

因此,这是一个持续的receive函数,用于收集所有入站消息

键入WSClientTest2(url:string)=
let onMessageReceived=新事件()
let responseMessage=新事件()
让ReceivedMessages=System.Collections.Concurrent.ConcurrentQueue()
let responseCallbacks=Map.empty unit)>
let manageMessage(消息:字符串)=
将message.Split(“:”)与
|[| id;message |]->
responseMessage.Trigger{Id=int(Id);Message=Message}
receivedMessages.Enqueue{Id=int(Id);Message=Message}
| _ -> ()
让startReceiving()=
设可变计数器=1
异步的{
//模拟从WebSocket接收
尽管如此
System.Threading.Tasks.Task.Delay 100 |>Async.AwaitTask |>Async.RunSynchronously
onMessageReceived.Trigger(sprintf“消息%d”计数器)
manageMessage(sprintf“%d:message”计数器)
计数器异步启动
做
startReceiving()
如何发送请求并等待相关响应消息?

这是我的尝试:

让可变请求ID=0
让sendRequest消息:字符串=
让requestId=requestId+1
let received=新事件()
let receivedCall=fun(msg:string)->
收到。触发消息
添加(requestId,receivedCall)|>忽略
让cancel=fun()->failwith“Timeout”
异步{
System.Threading.Thread.Sleep 500//等待x秒
取消
}|>异步启动
//一段时间后模拟发送/接收消息
让generateRequest()生成=
System.Threading.Thread.Sleep 100//等待响应的x时间
responseMessage.Trigger{Id=requestId;Message=Message}
generateRequest()
Async.AwaitEvent(received.Publish,cancel)
|>异步运行
Async.WaitWaitHandle似乎是正确的用法,但我不知道如何创建WaitHandle

我正在使用Async.AwaitEvent,但它似乎不起作用。
cancel()始终被调用,但不会引发任何异常

执行函数时等待事件,然后检查并返回其内容的正确方法是什么?

我还尝试使用一个映射来填充任何入站消息,但我仍然不知道如何“等待”正确的消息,而且可能需要检查孤立响应消息(增加复杂性)。
更一般地说,如果生成的代码非常糟糕,我更愿意在这个请求/响应场景中使用一个简单的API,并且只在实时更新时使用WebSocket。 我正在寻找一个很好的解决方案,否则我认为它不值得为性能着想,也不值得为我的需要着想