我是一个基于网络套接字的聊天应用程序(HTML5)。
浏览器通过wss打开与基于Java的Web套接字服务器的套接字连接。
当浏览器直接连接到服务器(没有任何代理)时,一切运行良好。
但是当浏览器位于企业代理后面时,浏览器套接字连接会在大约2分钟无活动后自动关闭。 浏览器控制台显示" Socket已关闭"。
在我的测试环境中,我有一个Squid-Dansguardian代理服务器。
IMP:如果浏览器没有任何代理连接,则不会出现此行为。
为了保持一些活动,我嵌入了一个简单的jquery脚本,它将每隔60秒向另一台服务器发出一个http GET请求。但它没有帮助。我仍然得到" socket关闭"在大约2分钟没有动作后,在我的浏览器控制台中。
欢迎任何帮助或指示。
由于
答案 0 :(得分:2)
在我看来,是一个功能,而不是一个错误。
在生产应用程序中,存在与所谓的“半开”套接字相关的问题 - see this great blog post about it。
连接突然丢失,导致TCP / IP连接断开而不通知对方连接。这可能由于许多不同原因而发生 - 无线信号或蜂窝信号丢失,路由器崩溃,调制解调器断开,电池耗尽,断电......
检测套接字是否实际打开的唯一方法是尝试发送数据...但是,您的代理可能无法安全地发送数据而不会干扰应用程序的逻辑 * 。
两分钟后,您的代理服务器会假设连接丢失并关闭套接字以节省资源并允许建立新连接。
如果您的代理未采取此预防措施,则在足够长的时间线上,所有可用资源都将通过永不关闭的断开连接获取,从而阻止访问您的应用。
两分钟很多。在Heroku上,他们将代理设置为50秒(更合理)。对于Http连接,这些超时通常要短得多。
最好的选择是在2分钟的时间内继续发送websocket数据。
Websocket协议通过实现内部ping机制解决了这个问题 - 使用它。这些ping应该由服务器发送,浏览器直接用pong响应它们(不涉及javascript应用程序)。
Javascript API(至少在浏览器上)不允许你发送ping帧(我猜这是一个安全问题,它阻止人们使用浏览器进行DoS攻击)。
一些开发人员的常见做法(我认为这是误解的)是实现一个JSON ping消息,该消息被服务器忽略或导致JSON pong。
由于您在服务器上使用Java,因此您可以访问Ping机制,我建议您实现它。
我还建议(如果你控制了代理)你将超时降低到更合理的50秒限制。
*生产过程中的情况实际上更糟......
因为存在一长串中介(家庭路由器/调制解调器,NAT,ISP,网关,路由器,负载均衡器,代理......),您的应用程序很可能成功发送数据,因为它仍然“连接”到其中一个中间人。
这应该会引起连锁响应,只会在一段时间后到达应用程序,并且只有在尝试发送数据时才会再次出现。
这就是Ping帧期望返回Pong帧的原因(意味着连接链是完整的。
<强> P.S。强>
您可能还应该抱怨Java应用程序在超时后关闭连接。在生产过程中,这种疏忽可能会迫使您经常重启服务器或遇到DoS情况(所有可用的文件句柄都将用于非活动的旧连接,并且您将没有空间进行新连接。)
答案 1 :(得分:1)
检查squid.conf中的request_timeout值。您可以通过request_timeout更改此设置。这将不仅仅影响Web套接字。例如,在我经常工作的环境中,命中perl脚本以生成各种配置。执行可能需要5-10分钟才能完成。必须提高httpd和squid服务器上的超时值以弥补这一点。
另外,请查看connect_timeout值。这默认为一分钟..