gpt4 book ai didi

c# - .NET WebSocket 无缘无故关闭

转载 作者:可可西里 更新时间:2023-11-01 02:38:16 44 4
gpt4 key购买 nike

我正在测试当客户端无法足够快地处理来自服务器端的数据时 .NET WebSockets 的工作方式。为此,我编写了一个持续向 WebSocket 发送数据的应用程序,但在接收循环中包含了人为延迟。正如预期的那样,一旦 TCP 窗口和其他缓冲区填满,SendAsync 调用开始需要很长时间才能返回。但几分钟后,SendAsync 抛出其中一个异常:

System.Net.HttpListenerException: The device does not recognize the command System.Net.HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request.

奇怪的是,这只发生在特定的消息大小和特定的时间。当允许客户端不受限制地读取所有数据时,连接是稳定的。此外,当客户端完全阻塞并且根本不读取时,连接保持打开状态。

通过 Wireshark 检查数据流表明是服务器在客户端的 TCP 窗口耗尽时重置 TCP 连接。

我试图遵循这个答案 ( .NET WebSockets forcibly closed despite keep-alive and activity on the connection ) 但没有成功。调整 WebSocket 保持事件间隔无效。另外,我知道最终应用程序需要能够优雅地处理意外断开连接,但如果可以避免,我不希望它们发生。

有人遇到过吗?我可以做一些超时调整吗?运行它应该会在一分半到三分钟之间产生错误:

class Program
{
static void Main(string[] args)
{
System.Net.ServicePointManager.MaxServicePointIdleTime = Int32.MaxValue; // has no effect

HttpListener httpListener = new HttpListener();
httpListener.Prefixes.Add("http://*/ws/");
Listen(httpListener);

Thread.Sleep(500);
Receive("ws://localhost/ws/");

Console.WriteLine("running...");
Console.ReadKey();
}

private static async void Listen(HttpListener listener)
{
listener.Start();
while (true)
{
HttpListenerContext ctx = await listener.GetContextAsync();

if (!ctx.Request.IsWebSocketRequest)
{
ctx.Response.StatusCode = (int)HttpStatusCode.NotImplemented;
ctx.Response.Close();
return;
}

Send(ctx);
}
}

private static async void Send(HttpListenerContext ctx)
{
TimeSpan keepAliveInterval = TimeSpan.FromSeconds(5); // tweaking has no effect
HttpListenerWebSocketContext wsCtx = await ctx.AcceptWebSocketAsync(null, keepAliveInterval);
WebSocket webSocket = wsCtx.WebSocket;

byte[] buffer = new byte[100];
while (true)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Binary, true, CancellationToken.None);
}
}

private static async void Receive(string serverAddress)
{
ClientWebSocket webSocket = new ClientWebSocket();
webSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(5); // tweaking has no effect

await webSocket.ConnectAsync(new Uri(serverAddress), CancellationToken.None);

byte[] receiveBuffer = new byte[10000];
while (true)
{
await Task.Delay(10); // simulate a slow client

var message = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
if (message.CloseStatus.HasValue)
break;
}
}

最佳答案

我不是 .NET 开发人员,但据我在 websocket 主题中看到的这类问题,在我看来,这些可能是原因:

  1. 两侧的 websocket 超时设置非常短。
  2. 客户端/服务器端运行时异常(除了日志记录,必须检查 onErroronClose 方法以了解原因)
  3. 互联网或连接失败。 Websocket 有时也会进入 IDLE 模式。你必须在 websockets 上实现一个心跳系统来保持它们的存活。使用 pingpong 数据包。
  4. 检查服务器端的最大二进制或文本消息大小。还设置一些缓冲区以避免消息太大时失败。

正如您所说,您的错误通常在一定时间内发生,1 和 2 必须帮助您。再次抱歉,如果我不能为您提供代码,但我在 java 中遇到了同样的问题,我发现这些是必须设置才能使用 websockets 的设置。搜索如何在您的客户端和服务器实现中设置这些,之后您一定没问题。

关于c# - .NET WebSocket 无缘无故关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49178595/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com