System.Net.WebSockets покидает сокеты в close_wait после отключения

У меня проблемы с закрытием соединения System.Net.WebSockets должным образом.

После некоторого поиска в Google даже нашел кого-то, кто объяснил, как это сделать правильно, но его собственные образцы оставляют сокет в close_wait.

Я буду использовать образцы этих людей, так как его объяснение было довольно хорошим, сообщение в блоге было здесь:

https://mcguirev10.com/2019/08/17/how-to-close-websocket-correctly.html

Примеры на github здесь:

https://github.com/MV10/WebSocketExample

Чтобы воспроизвести, проверьте репозиторий git

Создайте клиентское и серверное приложение с помощью System.Net.WebSockets:

dotnet build ./WebSocketExample/WebSocketExample.csproj
dotnet build ./WebSocketClient/WebSocketClient.csproj 

Запустите их:

./WebSocketExample/bin/Debug/netcoreapp3.0/WebSocketExample
./WebSocketClient/bin/Debug/netcoreapp3.1/WebSocketClient

Я запускаю это на Linux, поэтому ищу такие сокеты:

watch -n 2 'netstat -anp | grep ":8080" | grep "CLOSE_WAIT"'

Теперь на клиенте нажмите ESC, и появится сокет CLOSE_WAIT.
Это не было бы проблемой, если бы было всего несколько подключений, но когда мы говорим о сотнях / тысячах, мы столкнемся с ограничениями ресурсов.

Я знаю, что close_wait означает, что клиентское соединение отправило его close (FIN), и теперь сервер должен очистить / закрыть сокет.

Что не так в этом примере, что соединения не закрываются / не очищаются должным образом?


Редактировать:

Некоторая дополнительная информация, попробовал реализовать System.Net.WebSockets, который я нашел на github, и, похоже, он работает, как ожидалось:

https://github.com/ninjasource/Ninja.WebSockets

Я бы предпочел использовать тот, который находится в ядре.net, меньше кода для поддержки

1 ответ

Решение

Нашел обходной путь при использовании System.Net.WebSockets в системе отслеживания проблем github.net core.

Обсуждается здесь:https://github.com/dotnet/runtime/issues/27469

Решение вроде бы:

var context = listener.GetContext();
var res = context.Response;
res.StatusCode = 200;
res.OutputStream.Write(buffer, 0, buffer.Length);
res.OutputStream.Flush();
res.OutputStream.Dispose();
res.Close();    // the magic

Говорит, что он исправлен, не думаю, что он полностью исправлен, поскольку в настоящее время работает.net core 3.1, и без этого многие сокеты остаются в close_wait какое-то время.

Другие вопросы по тегам