Server-sent events (SSE) connection loss on mobile phones - javascript

I'm working on a website where some events are broadcasted to the clients using SSE (EventSource API). When testing my site on the mobile version of Chrome for Android, I noticed the connection is lost when the channel is idle for about five minutes.
I used several Android devices, with different carriers and different browsers and the result is the same, no matter if the screen is on or off. Desktop Chrome seems to keep the connection alive for a longer time.
Couldn't find any info about this, and when trying to debug the issue, all I got was a TCP "FIN" packet received from the telephone IP address about 3 and a half minutes after the last event was sent.
EventSource's onerror event doesn't get fired so I can't know when the connection was dropped to initiate a new one.
Is there any way to avoid this problem or should I just send some fake message every 30 secs to prevent connection idling?
Thanks in advance

Your connection was probably taken by a "push proxy" - a feature that is designed to improve battery life in phones.
Quote from "https://html.spec.whatwg.org/multipage/server-sent-events.html":
User agents running in controlled environments, e.g. browsers on
mobile handsets tied to specific carriers, may offload the management
of the connection to a proxy on the network. In such a situation, the
user agent for the purposes of conformance is considered to include
both the handset software and the network proxy.
For example, a browser on a mobile device, after having established a
connection, might detect that it is on a supporting network and
request that a proxy server on the network take over the management of
the connection. The timeline for such a situation might be as follows:
Browser connects to a remote HTTP server and requests the resource specified by the author in the EventSource constructor.
The server sends occasional messages.
In between two messages, the browser detects that it is idle except for the network activity involved in keeping the TCP connection alive,
and decides to switch to sleep mode to save power.
The browser disconnects from the server.
The browser contacts a service on the network, and requests that the service, a "push proxy", maintain the connection instead.
The "push proxy" service contacts the remote HTTP server and requests the resource specified by the author in the EventSource
constructor (possibly including a Last-Event-ID HTTP header, etc).
The browser allows the mobile device to go to sleep.
The server sends another message.
The "push proxy" service uses a technology such as OMA push to convey the event to the mobile device, which wakes only enough to
process the event and then returns to sleep.
This can reduce the total data usage, and can therefore result in
considerable power savings.

You can set the retry field to establish the reconnection time of EventSource instance
If the field name is "retry"
If the field value consists of only ASCII digits, then interpret the field value as an integer in base ten, and set the event stream's
reconnection time to that integer. Otherwise, ignore the field.

Related

How to check Network Connection quality between server and client in ASP.NET web application

in our website application, Our clients complaining about web site speed, they say it's keep waiting aroud 20secs, but when we check We see around 2 secs which is acceptable. We are guessing there is speed fluctuation, Maybe because of client's bad internet connection or server itself.
Could you please suggest me a way to detect this programmatically?
Let's just say, there will be a html button at that moment, user click's that to check connection quality between server and client, ping duration, speed etc. I wanna say, you have bad internet connection or there is a problem with server itself.

Set limit to re-connect attempts in MQTTjs?

I maintain an application which uses MQTT.js in the browser to communicate with remote devices.
Some customers attempt to use the application behind firewalls that disable websockets, causing thousands of reconnect errors. Our error monitoring tool will often throttle error reporting because of the high volume of errors generated by MQTT.js (some users will leave the app open for hours after a connection failure).
Is there a way to set limits on reconnect attempts in MQTT.js?

ServiceWorker LifeTime & Push Notifications

i have a question regarding to ServiceWorkers. I know that those Workers may be terminated by the user agent. Will a so terminated ServiceWorker be able to still receive Push Notifications and wake up to them?
If not, are there any information about how long the service is allow to run usually? I'm targeting Chrome on Desktop as well as Chrome Mobile.
I'm curious about how much i can rely on the workers and how much i can integrate them in my further apps.
Edit: What i really did not expected: If i go to this example and manually stop the Service Worker (should be equal to termination trough user agent) and then submit a push notification, the service worker gets resumed.
Therefore i assume that Push Notifications can wake up a terminated service worker. Is there any limitation?
A terminated service worker is still capable of handling a push event. The browser will start up the appropriate service worker when it detects an incoming push notification from the Web Push server (e.g., Google Cloud Messaging). The incoming push message includes registration information, which allows the browser to figure out which specific service worker to start up.
There are some requirements to fulfill in order for the browser to receive the incoming push notification from the Web Push server.
On desktop operating systems, the actual browser process needs to be running. So, for example, if you're a Chrome on OS X user and you quit Chrome, you won't receive any push notifications until you start up Chrome again. (At which point, a bunch might all flow in at once.)
On Android, the connection with the Web Push server is handled via the operating system, and Chrome (and I believe Firefox) does not have to be "running" in order to process the incoming notification and start up the correct service worker.

WebRTC DataChannel flow/control/back-pressure

The RTCDataChannel API does not provide any kind of flow/control or back-pressure, does this mean, that a sender could, theoretically, crash the browser of the receiver ? In my opinion the browser, (Chrome, Firefox, etc. all use SCTP under the hood), reads from the SCTP connection and schedules to run the js-callback consuming the packet. If the event queue cannot not keep up with the sender, the browser basically reads continuously packets while storing the packets in a buffer, which grows indefinitely. So when you connect two browsers, the sender can actually always overwhelm the other one, because there is no barrier like TCP receive windows or something similar.
This applies to the websocket api as well.
Do I just miss something or are these API just broken ? If I'm right, this would be a severe security issue when talking to unauthenticated browsers (in a torrent scenario for instance).
The webrtc data channel used to be based on UDP. During that time there was artificial throttling imposed by the browser in order to prevent network flooding. This was the case until chrome v32, I believe.
Nowadays the data channel is based on SCTP which has build-in flow control (FC) and there is no browser throttling any more (thank God). The parameters that control FC are not exposed through the API but that doesn't mean there is no FC.
I am not familiar with the implementation of webrtc in Chrome/FF but I don't think you can crash the browser with a simple flood attack. The "producer is faster than the consumer" is a pretty old problem.
That said, I have been working with the data channel, for more than an year now and have seen my browser crash almost on a daily basis, so there are probably many bugs in the webrtc implementation. Hopefully they won't pose any threat to security.
Sending big chunks of data useing webrtc data channel is not a particularly pleasant experience. The API doesn't offer a "channel is ready for write" callback or anything of the sort, so, yes!, you have to poll the bufferedamount value and try to keep it inside an optimal window. To add insult to injury bufferedamount used to be broken under Windows versions of Chrome, it was always 0. But I think they fixed this in chrome v37 or around that time.
IMHO the webrtc API is not very well thought through but it does the job and honestly I cannot think of any js API that is well thought through.

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.

Categories