使用System.Net.WebSockets.WebSocket,我在一个线程中有一个读循环。
var result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);我写的另一篇文章。
lock (ws)
ws.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None).Wait();这个很好用。
我的问题是,我如何才能干净利落地关闭这种联系?
任何试图关闭的尝试都会导致异常:
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", CancellationToken.None);
InvalidOperationException: 'Concurrent reads are not supported.'我尝试将一个CancellationToken传递给ws.ReceiveAsync,以便在接收循环中调用ws.CloseAsync。它没有中断ReceiveAsync调用,而是在下一条消息到达时返回。
是否可以干净地关闭read循环外的套接字。我可以实现一个“关闭连接”消息,但是当在WebSocket协议中有一个发送关闭消息的概念时,这似乎有点过分了。
发布于 2017-03-17 14:40:22
在这种情况下,您需要调用CloseOutputAsync并在读取中处理CloseSent消息类型。-斯蒂芬·克利里3月14日13时49分
您可以在另一个线程等待CloseOutputAsync时调用ReceiveAsync。
发布于 2017-03-14 12:50:22
我在这段代码中没有看到并发读取--如果您只从单个线程调用ReceiveAsync,并且在启动下一个线程之前等待操作的结果,则不应该出现此异常。扔到哪里去了?
编写部分的建议:如果使用锁和阻塞写入(使用.Wait()),则会阻塞完整线程(可能运行其他句柄),这可能不是您想要的。最好使用SemaphoreSlim,您可以这样做:
await semaphore.WaitAsync();
try
{
await ws.SendAsync();
}
finally
{
semaphore.Release();
}如果错误消息的文本不精确,而且实际上它抱怨并发的Send和Close,那么您也可以使用相同的信号量来保护Close调用:
await semaphore.WaitAsync();
try
{
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", CancellationToken.None);
}
finally
{
semaphore.Release();
}https://stackoverflow.com/questions/42782451
复制相似问题