Under what circumstances can reconnection actually occur with Server Sent Events? - javascript

I am using Server Sent Events for my small chat application, and I am storing a list of sent events on my server, along with passing an id field with SSE message.
Server Sent Events apparently has a concept of automatic reconnection, but I cannot seem to find a single instance where this actually occurs in practice.
For example, if you are on Android and tab out of the application, wait 30 seconds, and then tab back in, then the connection is broken. But the onerror event never occurs, and the readyState stays OPEN. So the only option to handle this situation seems to poll for heartbeats and do a manual reconnection by re-initializing the EventSource object if curr_time - last_heartbeat > heartbeat_interval
Another instance of disconnection is when you for example disable WiFI and then re-enable it. However, when this occurs, Android Chrome just automatically refreshes the page, so reconnection doesn't occur here either (instead it's just refresh which causes a disconnect and then a fresh connection).
So, am I missing something? SSE is touted as being very robust for its automatic reconnection ability, but I cannot find a single case where it actually performs a reconnection. What instances are there where a reconnection can actually occur, such that I can test this behavior?

Related

WebSockets not closing on IE if closing handshake is never made

I've been implementing a WebSocket with JavaScript and I have this one problem:
The endpoint that my web-application is connected to doesn't send back a close control frame when I'm sending it one.
This isn't that bad because browsers close the WebSocket connection after a while.
But a few things to notice are:
Browsers do only allow a specific amount of WebSockets to be connected at the same time.
When refreshing the web-application a new WebSocket is created
This causes the problem on IE:
When refreshing the web-application more than 6 times, a WebSocket connection cannot be made.
It seems like IE doesn't "delete" the WebSockets if they haven't been closed cleanly. And what's odd is that the amount of web sockets never seems to decrease by refreshing or just by waiting.
Only by closing the browser window, or the tab resets the number of WebSockets to 0.
I've done some researching and this is what I've found out:
Browsers do only support a specific amount of WebSockets to be connected at the same time.
IE supports 6 websockets to be connected [link]
Chrome supports 255 websockets to be connected [link].
And socket.onclose() isn't triggered when you do socket.close(), it is called when the endpoint responses with a close message. [link]
IE waits 15 seconds for the endpoint to send the close message [link].
Chrome waits for 60s for the responding message [Sorry, no link for this, found this out by testing].
If no response message is received, the browser closes the WebSocket connection and a TimeoutError should occur.
Please correct me if I'm wrong :)
I've tried to use unbeforeload to disconnect from the endpoint in hope that the browser would close the connection after a while, but with no luck. [link].
It can also be the cause of that IE aren't able to do request inside the unbeforeload function [link].
Question:
Is there any way to reset the number of WebSockets that are
connected in the browser to the endpoint with JavaScript?
Is there a way to disconnect a WebSocket from the endpoint immediately without closing the connection cleanly?
Is the only way to get this to work to inform the ones who host their endpoint make some changes so they do send a closing frame back?
Is there anything I've misunderstood or that I could try to get this to work?
Here is (in my opinion) good documentation about the WebSocket protocols if somebody would like to read more about it [link1] [link2].
UPDATE:
Only by refreshing the web-application on IE the WebSockets don't get destroyed.
If you navigate between pages in the web-application a new WebSocket will be made but the last WebSocket will get destroyed.
If it is just an edge case problem, then using a http fallback might be your only option. I guess you already do this for proxy servers that block socket connection away.
There is just 1 idea to verify (unconfirmed). Unfortunately, don't have access to IE to verify.
Application may open websocket connection in WebWorker/iFrame. During page refresh, "websocket connection scope" will be deleted, and connection is freed
EXPLANATION
This content from the question body:
Only by refreshing the web-application on IE the WebSockets don't get destroyed. If you navigate between pages in the web-application a new WebSocket will be made but the last WebSocket will get destroyed.
Says that Websocket connection is not destroyed ONLY when page refreshes. During normal navigation, everything is OK.
So, if websocket connection is opened within other scope which will be deleted during page reload, then hopefully connection will be destroyed.

node.js - how to get disconnect event with socket.io? [duplicate]

I have a client/server application using nodejs on the server and socket.io as the connection mechanism. For reasons relevant to my application I want to have only one active connection per browser, and reject all the connections from other tabs that may be opened later on during the session. This works great with WebSockets, but if WebSockets is not supported by the browser and XHR-polling is used instead, the disconnection never happens, so if the user just refreshes the page, this is not interpreted as a reconnection ( I have a delay for reconnection and session restoring), but as a new tab, which ends in the connection being rejected because the old connection made by this same tab is still active.
I'm looking for a way to effectively end the connection from the client whenever a refresh occurs. I've tried binding to the beforeunload and calling socket.disconnect() on the client side, and also sending a message like socket.emit('force-disconnect') and triggering the disconnect from the server with no success. Am I missing something here? Appreciate your help!
I've read this question and couldn't find it useful for my particular case.
Solved the issue, it turns out it was a bug introduced in socket.io 0.9.5. If you have this issue just update BOTH your server and client-side code to socket.io > 0.9.9 and set the socket.io client-side options sync disconnect on unload to true and you're all set.
Options are set this way:
var socket = io.connect('http://yourdomain.com', {'sync disconnect on unload' : true});
You can also get "Error: xhr poll error" if you run out of open file descriptors available. This is likely to happen during a load test.
Check the current open file descriptor size:
ulimit -n
Increase it to a high number:
ulimit -n 1000000

Channel disconnect notification in channel api in google app engine

Im using my GAE application on my phone. I face a problem in getting the disconnect notification to /_ah/channel/disconnected in channels api even if i manually close the socket by socket.close() function. the post occurs after a delay of say one minute. Does anyone know the way to speed things up? In my case socket.close() doesnt produce the channel disconnect notification(only in phone though.. it works perfectly from a laptop)!
The amount of time it takes the Channel API front-end servers to "realize" that a channel is disconnected is contingent on browser implementation.
On well-behaved browsers, we catch the beforeunload event and post a message to our front-end that says, "this client is going away." On other browsers, we may not get the event (or we may not be able to listen to it for various implementation reasons, like the browser sends it too often (FFFUUUU IE)) or once we get the event the XHR we send may get swallowed. In those cases, the frontend server realizes the client is gone because it fails to receive a heartbeat -- this is what's happening on your phone. (out of curiousity, what phone?)
Your case is interesting because you're explicitly calling onclose. The only thing this does is dispose the iframe that has the Channel FE code -- in other words, onclose just behaves as if the whole browser window was closed; it doesn't take advantage of the fact that the browser is still in a good state and could wait to close until a message is sent.
So I recommend two things: add a custom handler to your code (that does the same thing as your /_ah/disconnect handler) so you can just make an XHR when you know you're manually closing the channel. This is kludgy but functional. The bummer about this is you'll need to explicitly know your client id in your javascript code.
Second, add an issue to our issue tracker (http://code.google.com/p/googleappengine/issues/list) to request better disconnect notification when onclose is called explicitly.
Hope that helps; sorry there's not an easy answer right now.

Socket.IO: XHR-Polling delay on disconnection

I am working with socket.io and node.js. I'm am having problems tracking which users are online because of the few seconds delay before socket IO recognises an XHR-Polling client has disconnected.
If an XHR-Polling client refreshes the page their new connection message seems to precede their disconnection message. This causes confusion when trying to track which users are online.
One solution could be to detect the transport method on the serverside and delay the connection for XHR-Polling clients to ensure that the disconnection functions have been run first.
Has anyone had any experience of this?
The main problem with presence, as #davin and #jcolebrand point out in the comments, is that connections alone can't be relied upon. Network devices can hold on to connections after a user has navigated away from a page. So, you need something else in place to confirm a users presence.
This is something we've added support for in Pusher and we do this using something called Presence Channels.
We manage this using a unique user id, which you (the developer) have to supply when a user connects, in combination with a unique socket id which identifies the connection. Since this unique user id can only occur once within a presence member list it means that that user will only be listed once - even if they have multiple connections open, and thus multiple socket connections.
The same idea can be applied to HTTP connections.
The general approach for this is to use the session to uniquely identify the user. In that way even if they are just a "Guest" you can still identify them as long as they are allowing the use of cookies.
So, the number of users on your system should only ever max at the number of active sessions you have running on your server.
Hope this helps. Let me know if you'd like anything clarified.
I'm developping a chat support solution and the attendent have to know when a client connect. With websocket works fine, but with whr-pooling, sometimes the attendent just disconnect (with 5 seconds in some cases). Sometimes dont heppend. What I do: I just enter the page and wait looking the terminal app.
I'm using nodejs, nowjs
What version of socket.io are you using? I encountered this issue and solved it on this post. It turns out there was a bug introduced in socket.io 0.9.5 on the request sent when the beforeunload event was triggered that prevented the proper disconnection.

Can the unload Event be Used to Reliably fire ajax Request?

I need a method to monitor user edit sessions, and one of the solutions I'm reviewing will have me using an unload event to send an ajax request to inform the server of the end of the edit session. (See: Monitoring User Sessions to Prevent Editing Conflict)
My (rather limited) reading on the unload event indicates that the code attached to this handler has to run quickly, and as such, is usually used for clearing objects to prevent memory leaks.
My question is, can this work reliably enough for this purpose?
PS. I know about the async: false option.
This method is fairly reliable, if your server is fast enough to respond. Something to really watch out for though. If you close the browser and send AJAX request on unload event, there's a very good chance that the response isn't going to come back from the server in time before the window object is destroyed. What happens in this case (at least with IE) is that it will orphan your connection object and not terminate it correctly until the connection timeout is hit. If your server doesn't have connection keep-alive turned on, after you close 2 windows (while still having another window open), you will run out of open connections to the server (for IE6-7, for IE8 - 6 windows) and you will not be able to open your website until your connection timeout is hit.
I ran into a situation like that before were I was opening a popup window that was sending an AJAX request on unload, it was very reliable, but it was plagued by the issued described above, and it took really long time for me to track it down and understand what's going on. After that, what I did, is I made sure that opening window would have the same code to call server, and on every unload checked for the opener and ran the code there if it was present.
It seems that if you close the very last browser window, IE will destroy connection properly, but if one other window is open, it will not.
P.S. And just to comment on the answer above, AJAX is not really async. At least JS implementation of it isn't. After you send a request, you JS code is still going to be waiting for response from the server. It's not going to block your code execution, but since the server might take a while to response (or long enough for Windows to terminate IE window object) you might and probably will run into the problem described above.
Have you tried to use
var i = new Image(1,1);
i.src='http://...'
And just returning some empty image from server. I think it should be reliable, script will block. BTW: nice to add timestamp to prevent caching.
We have a case where we needed that. It's a report page that needs serious memory on the server so we wanted to free it immediately as soon as they left the page. We created a frameset and added the unload handler there. The most reliable way was to set the src of an image to the freeing script. We actually used both the unload and onbeforeunload for cross browser compatibility. It didn't work in web kit nightlies but management was OK with that.
However, that was not my proposed solution. I would use a heartbeat approach which involves more work but is much more robust.
Your page should send out periodical heartbeat requests. Each request sets the last heartbeat from a page. You then need a thread that runs on the server and clears memory if the last heartbeat was too long ago.
This doesn't solve the problem of leaving the page up for a long time. For that you need some monitoring for user activity and leave that page after a period of inactivity (make sure you confirm with the user)
You'll have to do your own testing about whether or not your particular scenario works with the time you have in unload, but making the AJAX request is pretty fast, since AJAX is asynchronous. You just send the request and then you're done! (Maybe you'll have to clear the request object you just created, though.)
If you wanted to verify that the AJAX request made it, then you'd have to worry more/use the async:false option (like this discussion indicates). But, just sending is a quick boom-and-you're-done operation.
I had a case in which I only needed to notify server side about the unload and didn't care about the response.
If thats your case you can ignore_user_abort and then you know it'll happen "reliably"

Categories