New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use native EventSource if available #20
Conversation
Now the tests always run the polyfill version. |
native EventSource in Firefox does not support broken TCP connections, this polyfill addes "heartbeat"-timeout, so it will reconnect periodically, when there are no messages from server; see https://bugzilla.mozilla.org/show_bug.cgi?id=444328 what do you think about? should native be used for Chrome? FF? |
I see, that makes it a bit more complicated. Is there any way to detect this bug without browser sniffing? |
seems, no |
So if I've understood correctly, this means EventSource in FF will work until the connection is broken (go offline, sleep laptop, etc.), then it will not automatically reconnect? |
do not know about sleep laptop and "go offline", but for situations, when the system have a wi-fi, but wi-fi access point looses internet(but wi-fi is still active), the users computer may not know, that there is a problem with internet |
What about something like: return if browserSupportsEventSource() and !eventSourceIsBuggy()
browserSupportsEventSource ->
typeof global.EventSource !== 'undefined'
eventSourceIsBuggy ->
navigator.userAgent.toLowerCase().indexOf('firefox') > -1 |
why do you think, that native ES is better? |
I don't have enough experience to say, it just seems like the correct behavior for a polyfill to use the native version if available. |
i don't think it is a good idea to use browser sniffing for that. |
IMO, if this works in all the common browsers, I don't mind and even prefer that it overrides the default for consistency. I think the goal is eventually for EventSource to be so fully and consistently supported that it makes this code irrelevant, but we're not there yet. |
Yeah, I agree with both comments. Still, it would be nice if there was a way to opt-out and use native ES if available. |
Are there any native EventSource implementations that are 100% correct? It would seem as a sensible effort to use native EventSource in browsers that got it right even on the basis that it should be cheaper resource-wise to use the compiled version instead of an interpreted one... |
@arteme , Chrome implementation is almost good https://code.google.com/p/chromium/issues/detail?id=260144 |
Ok, a little opinion here. I think EventSource as a spec is horrible. That said, it's pretty sweet that we can keep persistent connections open and use lightweight http streaming to receive realtime events from the server. If you never actually use the inbuilt EventSource implementation and always fall back to xhr long polling, then you might as well implement a more expressive api. If I am never going to benefit from a single open downstream connection over the lifetime of the page then I don't actually want to use this. |
@Matt-Esch, sorry, but how does it relate to that issue? |
You can use http streaming, but the browser doesn't recycle the buffer when done through xhr. So you have to close the connection at some sensible point to allow the buffer to be discarded. EventSource solves this problem. It triggers events for the data received over the http connection and then discards that portion of the response, so you don't risk leaking memory. Native event source is actually a reasonable alternative to websockets for heavy downstream. |
@Matt-Esch,
this technique should give a not bad result |
And what options are there for chrome? |
@Matt-Esch , i do not know about Chrome, may be Streams API ( https://dvcs.w3.org/hg/streams-api/raw-file/tip/Overview.htm ). so, |
Browser sniffing or direct CORS testing could be used to determine if the implementation on the current browser is acceptable.
Assuming that this advice is taken into account and a CORS request actually works, are there any implementations that still have bugs? I.e. are there any CORS compliant implementations that break with a 15 second server sent heartbeat? Is there something else that needs to be tested for? |
var m = /AppleWebKit\/(\d\d\d\.\d\d)/.exec(navigator.userAgent);
var isWebKitAfter537dot3 = m && Number(m[1]) > 537.3; ? |
Chrome and FireFox stops EventSource (readyState === CLOSED) in some rare cases: after clicking on And FireFox has two a little worse bugs: https://bugzilla.mozilla.org/show_bug.cgi?id=444328 - TCP-level keep alive timer |
Both of the firefox issues should be taken care of by generic application level keepalive logic that should be running for all implementations (reconnect manually if the heartbeat dies). There are many ways to disrupt the connection and the only robust way of knowing if it's working is to have your application receive a message from the server. Having said that, The first issue is certainly much more difficult to workaround. I'm curious to know if this happens even when the EventSource code is running in its own iframe? Might be worth testing. |
But according to information from https://bugzilla.mozilla.org/show_bug.cgi?id=444328#c1 - Chrome uses 45 seconds TCP keep-alive, so it should detect disconnects(although, only after some seconds);
|
Given the recommendation by w3c to send empty comments every 15 seconds from the server, reconnection issues are far less of a problem if there is some logic to listen for these comments and to reconnect when they stop making it through. But agreed, it would be nice if the reconnection logic in EventSource just worked. And by "first" I meant the disconnect on rare occasions problem such as downloading attachments. I'm not sure how to go about preventing certain actions from closing the connection prematurely. |
@Matt-Esch , for connection closing when "downloading attachments" this polyfill just does the reconnection The best way - to fix browsers implementation. |
Fixed |
This ensures native EventSource will be used if it's available.
As EventSource + CORS is now more widely supported, this seems like a better default.
Currently the tests just exit if native support is detected. Probably a better solution would be to (somehow) force the tests to use the polyfill version.