Abort() in ManagedWebsocket can't really abort socket when underlying TCP is half open
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Description
When TCP is half open, the client side's TCP is closed but server side doesn't know, the Websocket server can't use `ManagedWebsocket.Abort()` to close the socket immediately. The method `ManagedWebsocket.ReadAsync()` is still hung until underlying TCP can detect the termination.
### Reproduction Steps
1. Set up a Websocket server using .net
2. Make a Websocket connection to the server. Make sure the connection is connected.
3. Half close the underlying TCP. I tried to disconnect the network cable of the client side. And wait for client side reporting the connection is disconnected.
4. call Abort() from server side.
5. You can see the `ReadAsync()` returns around 5-6 minutes later.
### Expected behavior
When I call `Abort()`, `ReadAsync` and `WriteAsync` should return immediately even the underlying TCP is half open.
### Actual behavior
`ReadAsync` stuck until the TCP detects the disconnection.
### Regression?
_No response_
### Known Workarounds
Use cancellation token to terminate `ReadAsync`
### Configuration
.Net 5, Debian 10
### Other information
The problem is _stream doesn't have right behavior when called `Dispose()`. It still stuck in `ReadAsync` and doesn't return.
https://github.com/dotnet/runtime/blob/46db4aa3c505ac36cf8d0d612d4161bb7239ed87/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs#L215
The HttpRequestStream doesn't implement close method.
https://github.com/dotnet/aspnetcore/blob/main/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs
Contributor guide
Assessment
This issue has not been assessed yet.