相关疑难解决方法(0)

尽管在连接上保持活动和活动,.NET WebSockets仍强制关闭

我们使用System.Net.WebSockets编写了一个简单的WebSocket客户端.ClientWebSocket上的KeepAliveInterval设置为30秒.

连接成功打开,流量按预期在两个方向上流动,或者如果连接空闲,客户端每30秒向服务器发送一次Pong请求(在Wireshark中可见).

但是在100秒之后,由于TCP套接字在客户端被关闭,连接突然终止(在Wireshark中观察我们看到客户端发送FIN).在关闭套接字之前,服务器以1001 Going Away响应.

经过大量的挖掘,我们已经找到了原因并找到了一个相当沉重的解决方法.尽管有很多Google和Stack Overflow搜索,我们只看到了其他几个人发布关于这个问题的例子,没有人回答,所以我发布这个以拯救他人的痛苦,并希望有人能够建议一个更好的解决方法.

100秒超时的来源是WebSocket使用System.Net.ServicePoint,它具有MaxIdleTime属性以允许关闭空闲套接字.在打开WebSocket时,如果Uri存在现有的ServicePoint,它将使用它,无论MaxIdleTime属性在创建时设置为什么.如果没有,将创建一个新的ServicePoint实例,MaxIdleTime根据System.Net.ServicePointManager MaxServicePointIdleTime属性的当前值设置(默认为100,000毫秒).

问题是,就ServicePoint空闲计时器而言,WebSocket流量和WebSocket保持活动(Ping/Pong)似乎都不会注册为流量.因此,在打开WebSocket之后100秒,它就会被拆除,尽管有交通或保持活动.

我们的预感是,这可能是因为WebSocket作为HTTP请求启动,然后升级到websocket.似乎空闲计时器仅查找HTTP流量.如果确实发生了这似乎是System.Net.WebSockets实现中的一个主要错误.

我们使用的解决方法是将ServicePoint上的MaxIdleTime设置为int.MaxValue.这允许WebSocket无限期保持打开状态.但缺点是该值适用于该ServicePoint的任何其他连接.在我们的上下文(使用Visual Studio Web和负载测试进行负载测试)中,我们为同一个ServicePoint打开了其他(HTTP)连接,实际上在我们打开WebSocket时已经存在一个活动的ServicePoint实例.这意味着在我们更新MaxIdleTime之后,Load测试的所有HTTP连接都没有空闲超时.这感觉不太舒服,但实际上Web服务器应该关闭空闲连接.

我们还简要探讨了是否可以创建一个仅为我们的WebSocket连接保留的新ServicePoint实例,但是看不到干净的方法.

另一个使得更难追踪的小扭曲是,虽然System.Net.ServicePointManager MaxServicePointIdleTime属性默认为100秒,但Visual Studio会覆盖此值并将其设置为120秒 - 这使得搜索更加困难.

.net c# websocket

15
推荐指数
2
解决办法
3685
查看次数

标签 统计

.net ×1

c# ×1

websocket ×1