System.Net.WebSockets 断开连接后将套接字留在 close_wait
System.Net.WebSockets leaving sockets in close_wait after disconnect
我在正确关闭 System.Net.WebSockets 连接时遇到问题。
经过一些谷歌搜索甚至找到了解释如何正确执行此操作的人,但他自己的示例在 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 套接字。
如果只有几个连接,这不会是个问题,但在谈论 hundreds/thousands 时,我们会 运行 进入资源限制。
我知道 close_wait 表示客户端连接已发送关闭 (FIN),现在由服务器清理 up/close 套接字。
此示例中的连接不正确 closed/cleaned 有什么问题?
编辑:
一些额外的信息,尝试了我在 github 上发现的 System.Net.WebSockets 的实现,并且它似乎确实按预期工作:
https://github.com/ninjasource/Ninja.WebSockets
我宁愿使用 .net core 中的那个,维护的代码更少
找到了在 .net 核心 github 问题跟踪器上使用 System.Net.WebSockets 时的解决方法。
这里讨论:
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 中停留一段时间。
我在正确关闭 System.Net.WebSockets 连接时遇到问题。
经过一些谷歌搜索甚至找到了解释如何正确执行此操作的人,但他自己的示例在 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 套接字。
如果只有几个连接,这不会是个问题,但在谈论 hundreds/thousands 时,我们会 运行 进入资源限制。
我知道 close_wait 表示客户端连接已发送关闭 (FIN),现在由服务器清理 up/close 套接字。
此示例中的连接不正确 closed/cleaned 有什么问题?
编辑:
一些额外的信息,尝试了我在 github 上发现的 System.Net.WebSockets 的实现,并且它似乎确实按预期工作:
https://github.com/ninjasource/Ninja.WebSockets
我宁愿使用 .net core 中的那个,维护的代码更少
找到了在 .net 核心 github 问题跟踪器上使用 System.Net.WebSockets 时的解决方法。
这里讨论: 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 中停留一段时间。