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 = private static readonly Action<ILogger, DateTime, string, Exception> _errorWritingFrame =
LoggerMessage.Define<DateTime, string>(LogLevel.Error, 11, "{time}: Connection Id {connectionId}: Error writing frame."); 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 // Category: ServerSentEventsTransport
private static readonly Action<ILogger, DateTime, string, int, Exception> _sseWritingMessage = 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."); 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) public static void SSEWritingMessage(this ILogger logger, string connectionId, int count)
{ {
if (logger.IsEnabled(LogLevel.Debug)) if (logger.IsEnabled(LogLevel.Debug))

View File

@ -178,7 +178,16 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Transports
{ {
_logger.SendPayload(_connectionId, buffer.Length); _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) 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() var options = new WebSocketOptions()
{ {
CloseTimeout = TimeSpan.FromSeconds(1) CloseTimeout = TimeSpan.FromMilliseconds(100)
}; };
var ws = new WebSocketsTransport(options, transportSide, connectionId: string.Empty, loggerFactory: new LoggerFactory()); var ws = new WebSocketsTransport(options, transportSide, connectionId: string.Empty, loggerFactory: new LoggerFactory());