Created
October 15, 2011 13:20
-
-
Save gdamjan/1289552 to your computer and use it in GitHub Desktop.
watchdog for longpoll connections in a browser - the demo gevent server pings the browser 10 times, then stalls. The javascript watchdog should detect this and abort the connection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function xhr_watchdog(httpRequest, interval) { | |
| const max_tries = 2 | |
| function _watchdog(last_length, n) { | |
| if (httpRequest.readyState <= 3) { | |
| var new_length = httpRequest.responseText.length | |
| if (new_length > last_length) { | |
| document.body.innerHTML +="Connection alive<br>\n" | |
| window.setTimeout(_watchdog, interval, new_length, max_tries) | |
| } else if (n > 0) { | |
| n = n - 1; | |
| document.body.innerHTML +="Let's give it another try " + n + "<br>\n" | |
| window.setTimeout(_watchdog, interval, new_length, n) | |
| } else { | |
| document.body.innerHTML +="Aborting<br>\n" | |
| httpRequest.abort() | |
| } | |
| } else if (httpRequest.readyState == 4) { | |
| document.body.innerHTML +="Connection normally closed: " + httpRequest.status + "<br>\n" | |
| } | |
| } | |
| window.setTimeout(_watchdog, interval, 0, max_tries) | |
| } | |
| if (typeof window.XMLHttpRequest !== "undefined") { | |
| newXMLHttpRequest = function () { return new window.XMLHttpRequest() } | |
| } else if (typeof window.XDomainRequest !== "undefined") { | |
| newXMLHttpRequest = function () { return new window.XDomainRequest() } | |
| } else { | |
| newXMLHttpRequest = function () { | |
| try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } | |
| catch (e) {} | |
| try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } | |
| catch (e) {} | |
| try { return new ActiveXObject("Microsoft.XMLHTTP"); } | |
| catch (e) {} | |
| //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant | |
| throw new Error("This browser does not support XMLHttpRequest."); | |
| } | |
| } | |
| var httpRequest = newXMLHttpRequest() | |
| httpRequest.open('GET', '/longpoll?heartbeat=10000', true) | |
| httpRequest.send(null) | |
| xhr_watchdog(httpRequest, 10000) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python2 | |
| # pip2 install --user hg+https://bitbucket.org/snaury/greenlet#egg=greenlet | |
| # pip2 install --user gevent | |
| from gevent.pywsgi import WSGIServer | |
| import gevent | |
| import urlparse | |
| def application(env, start_response): | |
| if env['PATH_INFO'] == '/longpoll': | |
| query = urlparse.parse_qs(env['QUERY_STRING']) | |
| heartbeat = float(query.get('heartbeat', ['10000'])[0]) / 1000 | |
| start_response('200 OK', [('Content-Type', 'application/json')]) | |
| for i in range(10): | |
| yield ".\n" | |
| gevent.sleep(heartbeat) | |
| print "now stalling" | |
| gevent.sleep(10 * heartbeat) | |
| yield "end of stream" | |
| elif env['PATH_INFO'] in ('/', '/index.html'): | |
| start_response('200 OK', [('Content-Type', 'text/html')]) | |
| yield """<html><head> | |
| <script src="/script.js" type="text/javascript"></script> | |
| </head></html>""" | |
| elif env['PATH_INFO'] == '/script.js': | |
| start_response('200 OK', [('Content-Type', 'application/x-javascript')]) | |
| yield file('longpoll-xhr-watchdog.js').read() | |
| else: | |
| start_response('400 Not Found', [('Content-Type', 'text/plain')]) | |
| yield "Not Found" | |
| if __name__ == "__main__": | |
| print 'Serving on 8088...' | |
| WSGIServer(('', 8088), application).serve_forever() |
Author
gdamjan
commented
Oct 15, 2011
- works in Firefox (afaik 4 and up)
- works in Chromium (14 at least)
- so far doesn't work in Android browser - since obviously it doesn't update httpRequest.responseText in readyState == 3.
- IE 6 doesn't work
- IE 7 might work
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment