Ignore failed send after close (WebSockets) (#593)

This commit is contained in:
BrennanConroy 2017-06-27 10:01:45 -07:00 committed by GitHub
parent 4c88a19262
commit e36da30072
3 changed files with 29 additions and 2 deletions

View File

@ -90,6 +90,9 @@ namespace Microsoft.AspNetCore.Sockets.Internal
private static readonly Action<ILogger, DateTime, string, Exception> _errorWritingFrame =
LoggerMessage.Define<DateTime, string>(LogLevel.Error, 11, "{time}: Connection Id {connectionId}: Error writing frame.");
private static readonly Action<ILogger, DateTime, string, Exception> _sendFailed =
LoggerMessage.Define<DateTime, string>(LogLevel.Trace, 12, "{time}: Connection Id {connectionId}: Socket failed to send.");
// Category: ServerSentEventsTransport
private static readonly Action<ILogger, DateTime, string, int, Exception> _sseWritingMessage =
LoggerMessage.Define<DateTime, string, int>(LogLevel.Debug, 0, "{time}: Connection Id {connectionId}: Writing a {count} byte message.");
@ -302,6 +305,14 @@ namespace Microsoft.AspNetCore.Sockets.Internal
}
}
public static void SendFailed(this ILogger logger, string connectionId, Exception ex)
{
if (logger.IsEnabled(LogLevel.Trace))
{
_sendFailed(logger, DateTime.Now, connectionId, ex);
}
}
public static void SSEWritingMessage(this ILogger logger, string connectionId, int count)
{
if (logger.IsEnabled(LogLevel.Debug))

View File

@ -178,7 +178,16 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Transports
{
_logger.SendPayload(_connectionId, buffer.Length);
await ws.SendAsync(new ArraySegment<byte>(buffer), _options.WebSocketMessageType, endOfMessage: true, cancellationToken: CancellationToken.None);
if (WebSocketCanSend(ws))
{
await ws.SendAsync(new ArraySegment<byte>(buffer), _options.WebSocketMessageType, endOfMessage: true, cancellationToken: CancellationToken.None);
}
}
catch (WebSocketException socketException) when (!WebSocketCanSend(ws))
{
// this can happen when we send the CloseFrame to the client and try to write afterwards
_logger.SendFailed(_connectionId, socketException);
break;
}
catch (Exception ex)
{
@ -189,5 +198,12 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Transports
}
}
}
private static bool WebSocketCanSend(WebSocket ws)
{
return !(ws.State == WebSocketState.Aborted ||
ws.State == WebSocketState.Closed ||
ws.State == WebSocketState.CloseSent);
}
}
}

View File

@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
{
var options = new WebSocketOptions()
{
CloseTimeout = TimeSpan.FromSeconds(1)
CloseTimeout = TimeSpan.FromMilliseconds(100)
};
var ws = new WebSocketsTransport(options, transportSide, connectionId: string.Empty, loggerFactory: new LoggerFactory());