Skip to content

WebSocket gracefull shutdown exception #604

Open

Description

@osexpert

Hi,
I have regular .net clients and aspNetCore server. When client closes I call webSocket.CloseOutputAsync. This works, I get no exceptions on client or server.

But when trying to do the same on server, it always generate exception, and I tried both webSocket.CloseAsync or webSocket.CloseOutputAsync. With webSocket.CloseOutputAsync I get an exeption on server happens here in WebSocketMessageHandler.cs:

      if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await this.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed as requested.", CancellationToken.None).ConfigureAwait(false);
                        return null;
                    }

Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Private.CoreLib.dll
The WebSocket is in an invalid state ('Closed') for this operation. Valid states are: 'Open, CloseReceived, CloseSent'

I changed the code to this and it seems to fix the exception, but not sure if its the correct fix:

if (result.MessageType == WebSocketMessageType.Close)
                    {
                        if (this.WebSocket.State == WebSocketState.CloseReceived)
                            await this.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed as requested.", CancellationToken.None).ConfigureAwait(false);
                        return null;
                    }

Activity

  1. osexpert commented on Nov 4, 2020

    @osexpert
    Author

    Or maybe just check for all the valid states 'Open, CloseReceived, CloseSent'

  2. AArnott commented on Nov 4, 2020

    @AArnott
    Member

    I'm afraid web socket termination is an area I'm not too familiar with either. We occasionally have unit test failures in this area. If you or anyone else learns of a fix to this library for it, I'd love to hear it.

  3. osexpert commented on Nov 4, 2020

    @osexpert
    Author

    I can only suggest to prevent the exception by calling CloseAsync only for the allowed states as presented by exception. It might not really fix anything, but it does not crash anymore:-)

    if (result.MessageType == WebSocketMessageType.Close)
    {
        if (this.WebSocket.State == WebSocketState.Open 
          || this.WebSocket.State == WebSocketState.CloseReceived 
          || this.WebSocket.State == WebSocketState.CloseSent)
            await this.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed as requested.", CancellationToken.None).ConfigureAwait(false);
        return null;
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions