ASP.NET Core应用程序在客户端使用websocket连接,在服务器端使用Microsoft.AspNetCore.WebSockets.Server 0.1.0(nuget上的最新稳定版本)。简单的发送代码是
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
问题是这条线在关闭连接时抛出错误。如果进程成功,我希望该方法返回一个布尔值。我已经检查连接是否打开如下:
_ws.State == WebSocketState.Open
但如果用户有此功能,则无效 拔掉网线或断开设备(几乎所有情况除了关闭浏览器)。
作为一个额外的,我不知道如何模拟两个客户端之一的网络连接丢失和我认为WebSocketState是只读的,请警告我,如果我错了我不认为更短的ping会解决这个问题。 我有两个想法:
我可以在try catch块中使用发件人代码。 (我对在生产代码中使用try catch感到不舒服)
我可以在客户端设置间隔,并向服务器询问“对我来说什么是新的”。我觉得这很糟糕,因为它远不是一个websocket(更接近http)。
有没有办法解决这个问题而不使用try catch?我知道这不是一个合格的问题,但对我来说是一个合格的问题。如果需要,我可以分享完整的代码。
:
虽然消息在生产环境中运行良好,但我通过拔下网络电缆并将数据发送到客户端来断开客户端连接。我使用try catch而没有捕获。然后我得到 this 错误。
这意味着我无法通过使用try catch来检测丢失的连接。我想我可以通过处理这个投掷来解决这个问题。
如何处理此错误?
我注意到“由于c#6 link ,因此”异常无效方法的异常无法捕获“和”可以在catch中使用等待“但是我可以如果我不能以这种方式解决问题,我可以尝试同步await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk).runsynchronously();
。
同步运行没有帮助。使用try catch没有区别。结果提问,asp.net核心websocket如何ping?
使用Microsoft.aspnetcore.websockets.server 0.1.0时的日志文件
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HL1940BSEV8O": An unhandled exception was thrown by the application.
System.IO.IOException: Unexpected end of stream
at Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.<EnsureDataAvailableOrReadAsync>d__38.MoveNext()
使用Microsoft.aspnetcore.websockets 1.0.0时的日志文件
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HL19H5R4CS21": An unhandled exception was thrown by the application.
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Error -4077 ECONNRESET connection reset by peer ---> Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4077 ECONNRESET connection reset by peer
答案 0 :(得分:6)
我可能会遗漏某些内容,但为什么无法以下列方式将发送操作包装在返回bool
的方法中:
private async Task<bool> DoSend()
{
bool success = true;
try
{
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
}
catch (Exception ex)
{
// Do some logging with ex
success = false;
}
return success;
}
我还建议阅读有关Async All The Way的内容,它应该清除async void
,async Task
和async Task<T>
答案 1 :(得分:0)
在C#6.0中捕获异步方法的异常之前,您应该使用ExceptionDispatchInfo类型。然后代码将如下所示:
private async Task<bool> DoSend()
{
bool success = true;
ExceptionDispatchInfo capturedException = null;
try
{
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
}
catch (Exception ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
}
if (capturedException != null)
{
await ExceptionHandler();
if (needsThrow)
{
capturedException.Throw();
}
}
success = capturedException == null;
return success;
}