dal*_*las 7 javascript comet xmlhttprequest
我已经实现了一个长轮询连接,允许我使用Tomcat Web服务器和前端的标准javascript进行服务器端推送(彗星).为了保持连接,我有一个简单的保持活动循环,一旦最后一个完成/失败就会启动一个新的请求.
绝大多数时候,这种连接完全正常,并且像我期望的那样保持活力.但是,我注意到当用户的互联网连接断开时(例如,他们断开VPN连接,拔掉他们的以太网等)并且我有一个待处理的XMLHttpRequest出服务器,我没有得到任何失败的迹象.因此,连接无声地死亡,我不知道它发生了,除非我经常向服务器发送请求以测试连接(这似乎打败了使用长轮询的目的).
这是我在Chrome中看到的请求对象,当它死于这个沉默的死亡时:
request: XMLHttpRequest
onabort: function ()
onerror: function ()
onload: null
onloadend: null
onloadstart: null
onprogress: null
onreadystatechange: function ()
readyState: 1
response: ""
responseText: ""
responseType: ""
responseXML: null
status: [Exception: DOMException]
statusText: [Exception: DOMException]
upload: XMLHttpRequestUpload
withCredentials: false
Run Code Online (Sandbox Code Playgroud)
我有三个监听器(onabort,onerror,onreadystatechange)设置来警告消息,如果它们被解雇,但每当我连接到服务器时,我什么也得不到.这是我正在形成请求的方式:
var request = new XMLHttpRequest();
//url is just the url to my servlet to handle this
request.open("GET", url, true);
//handlestatechange is just my standard handling code
//that I've put an alert at the top of
request.onreadystatechange = handleStateChange;
request.onerror = function()
{
alert("We encountered an error");
}
request.onabort = function()
{
alert("I've had an abortion");
}
request.send(null);
Run Code Online (Sandbox Code Playgroud)
看起来这将是一个非常标准的情况,但我没有看到任何关于如何允许长轮询连接从这种断开恢复的对话.
难道我做错了什么?有没有其他更标准的方法来做长轮询/彗星来绕过这个问题?
任何有关这方面的帮助将不胜感激,谢谢
我认为处理此问题的最佳方法是将长轮询请求的持续时间限制在某个时间T(例如 60 秒是一个不合理的值),然后在客户端中使用超时来检测停滞状态。理想情况下,您可以使用 XHRtimeout属性来执行此操作,但它不支持 x-browser,尽管它在 W3C 规范中。因此,您需要使用setTimeout和来实现您自己的支持xhr.abort()。
然后,客户端可以假设,如果他们在 T 秒内没有得到响应,则连接已停止,并且适合中止当前请求并尝试重新连接。
这工作得相当好,但确实意味着在检测客户端连接何时停止时存在一些延迟(最多 T 秒)。对于长期民意调查请求,我不知道对此有什么要做的。如果您确实需要更好的解决方案,那么您可能需要查看发送回心跳消息或WebSockets 的流式彗星连接。
这就是简单的答案。不幸的是,事实证明这是一个不平凡的问题,涉及各种奇怪的边缘情况。例如,您可能关心也可能不关心连接超时的代理服务器,或者更改用户计算机上的默认 TCP 超时的各种方式。这就是为什么我们看到像Socket.IO这样的框架出现,隐藏了很多这种丑陋之处。
PS 可能值得注意的是,您可以通过 监视某些浏览器中的在线状态navigator.onLine,但它的支持很差。它真正运行正常的唯一浏览器是 Chrome。它唯一真正告诉您的是用户是否因某种原因离线。它无法告诉您他们有工作联系。
| 归档时间: |
|
| 查看次数: |
4190 次 |
| 最近记录: |