Problems with XMLHttpRequests long polling and intermittent network connections

I implemented a long polling connection to allow me to do a server-side comet push using the Tomcat web server and standard javascript on the interface. To maintain a connection, I have a simple keep-alive loop that initiates a new request as soon as the last one completes / shuts down.

The vast majority of the time, this relationship works just fine and persists as I expect. But I noticed that when the user Internet connection drops out (for example, they disconnect from the VPN, disconnect their ethernet, etc.) And I have a pending XMLHttpRequest on the server, I do not see any signs of failure. Because of this, the connection freezes silently, and I can’t know what happened if I constantly send requests to the server to check the connection (which does not seem to allow a long poll).

Here's the request object that I see in Chrome when it dies this silent death:

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 

I have three listening methods (onabort, onerror, onreadystatechange) to alert the message if they ever fire, but I get nothing when I take my connection to the server. This is how I form the request:

 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); 

It seems like this would be a pretty standard situation, but I have not seen any talk about how to allow a long voice connection to recover from such disconnections.

Am I doing something wrong? Is there an even more standard approach to long polling / comets that circumvents this problem?

Any help with this would be greatly appreciated. Thanks

+7
source share
1 answer

I believe that the best way to deal with this is to limit the length of long polling requests to some time, T (for example, 60 seconds is a non-unreasonable value), and then use the timeout in the client to detect stalled conditions. Ideally, you would do this using the XHR timeout property, but it is not supported by the x browser , even though it is in the W3C specification.Thus, you will want to implement your own support with setTimeout and xhr.abort() .

Clients can then assume that if they do not receive a response within t seconds, the connection is stalled and it would be necessary for it to abort the current request and try to reconnect.

This works quite well, but it does mean that some latency is detected when the client connection is stuck (up to T seconds). For queries with a long survey, I don’t know that much can be done about this. If you really need a better solution, you can see the streaming comet link that sends heartbeat or WebSockets response messages.

This is a simple answer. Unfortunately, this turns out to be a non-trivial problem with all kinds of cases of extreme cases. For example, you may or may not have to worry about proxies with a connection timeout or the various ways in which the default TCP timeout can be changed on your users computers. That's why we saw frameworks like Socket.IO that hide a lot of this ugliness.

PS It’s probably worth noting that you can control the status online in some browsers via navigator.onLine , but it is poorly supported . The only browser that it really behaves to is Chrome. The only thing this really tells you is that the user for some reason does not work offline. He cannot tell you that they have a working connection.

+2
source

All Articles