How to solve Chrome's 6 connection limit when using xhr polling - google-chrome

I recently found out that Chrome seems to have a connection limit of 6 ( Chrome hangs after certain amount of data transfered - waiting for available socket ) unfortunately I found this out the hard way by getting a "waiting for available sockets" message after loading up too many tabs (7).
I know it is Chrome since another Chrome user (a.k.a another browser session) loads the web page perfectly fine on the same computer at the same time (I have multiple Chrome users open on my computer). So it is not the server in any way.
I believe this is because, in socket.io (which I am using for notifications), I am xhr-polling which is causing Chrome to have to wait until it can grab a socket from one of those connections before it can process the page.
What is the solution to this?
I have thought of a couple of solutions:
make the xhr-polling window smaller, this increases connections in the browser and node.js but will mean the page won't stall.
Use websockets. I am unsure if websockets are immune to this problem either.
Make connections inactive on tabs not focused. Though it seems other sites don't have to do that...
Use some kind of connection sharing. Considering that Chrome isolates websockets and xhr requests to the tab I do find it difficult to understand how that works.
As an added point: the reason I have not gone with websockets from the start is because I use cloudflare. But if this is the way to solve it then: so be it.

Use a real webSocket, rather than XHR Polling. webSocket connections do not count toward the http connection limit to the same origin.
There is a separate global limit to how many webSocket connections can be created, but it is a high number (200 in Firefox - not sure what it is exactly in Chrome).
Here are some references on this topic:
Max parallel http connections in a browser?
Maximum concurrent connections to the same domain for browsers
HTTP simultaneous connections per host limit… are per tab, browser instance or global?.

Related

Chrome Queueing Requests

Chrome Timing View
The image above show chrome spends most of the time queuing up the request. I am trying to figure out why that is happening to minimize it.
According to chrome developer documents:
A request being queued indicates that:
The request was postponed by the rendering engine because it's
considered lower priority than critical resources (such as
scripts/styles). This often happens with images.
The request was put on hold to wait for an unavailable TCP socket that's about to free up.
The request was put on hold because the browser only allows six TCP connections per origin on HTTP 1.
Time spent making disk cache
entries (typically very quick.)
Number 3 seems to be the most likely problem according to chrome developer documents but I know that only one request is going out at a time so that can't be it. I don't think it is number 1 either because the performance monitor doesn't show a lag from rendering. Maybe it is either 2 or 4 but I don't know how to test that.
Chrome Performance Monitor
I've included a picture of the performance monitor that shows these long tasks where something is happening in the system. These are also a mystery to me and seem related.
Any help is greatly appreciated!
Edit: It seems you can disable the disk cache when you open dev tools and that didn't seem to fix the problem.

websocket receive buffer in Chrome

I have an application in which I open a websocket from a browser (Chrome, in my case) to a server, then I start sending messages from the server side to the browser. What I am finding is that when I send messages too quickly from the server, messages start getting buffered up on the browser side. This means that the browser "falls behind" and ends up processing messages sent long ago by the server, which in my application is undesirable.
I have eliminated the following possible candidates for where this buffering is happening:
The server. I can kill the server process entirely and I see that messages continue to be received by my javascript code for several minutes, so the buffering is not happening inside the server process.
The network. I can reproduce the same issue when running the server on the same machine as my web browser, and the amount of data that I am sending is far below the bandwidth constraints for a TCP connection to localhost.
This leaves the browser. Is there any way I can (a) determine the size of the buffer chrome is maintaining for my websocket, or (b) reduce the size of this buffer and cause chrome to drop frames?
(a) Chrome buffers around 128KB per WebSocket connection. The amount
of buffered data is not visible to the application.
(b) Chrome will never intentionally drop frames (this would violate the standard).
When the processing done by Javascript is trivial, Chrome can handle over 50 MB per second over a WebSocket. So it sounds like the processing you are doing is non-trivial. You can drop messages that are too old in the onmessage handler (but please bear in mind that the clock on the client may be out-of-sync with the clock on the server).
If the main thread of the browser is always busy, even dropping messages may not be enough to keep up. I recommend the "Performance" tab in Chrome Devtools as a good way to see where your application is spending its time.

Chrome - multiple requests

Whenever I send a GET-request to my webapp using chrome, according to my apache access log two identical requests (not always, but most of the times, I can't reproduce it - it's not for the favicon) get send to the sever, although only one is shown in the chrome dev tools. I deactivated all extensions and it's still happening.
Is this https://news.ycombinator.com/item?id=1872177 true and is it a chrome feature or should I dig deeper within my app to find the bug?
I think it's even worse than that. My experience here (developing with Google App Engine), is that Chrome is making all kinds of extra requests.
This is possibly due to the option that is in the Settings, checked by default:
Predict network actions to improve page load performance
Here is a really weird example: my website's page runs a notifications check every 15 seconds (done in javascript). Even after closing all tabs related to my website, I see requests coming from my IP, some random pages but also the notification check request. To me that means that Chrome has a page of my website running in the background and is even evaluating its javascript.
When I request a page, I pretty much always get another request for one of the links in that page. And it also requests resources of the extra pages (.css, .js, .png files). Lots of requests going on.
I have seen the same behavior with the development server that runs locally.
Happens also from another computer / network.
Doesn't happen with Firefox.
Also, see What to do with chrome sending extra requests?

Chrome websocket connection delay

I have a weird problem with websockets and chrome (22.0.1229.79m) (I haven't coded authentication for other browsers yet so I cant test them). It seems like if I reload chrome 3 times, there will be a huge delay in connecting to my websocket server. The server is not delaying the connection, I tested this by connecting to it with another PC while chrome was delaying and it connected perfectly.
Is there anyway to fix this? This is a problem when I am switching servers receiving data. It will halt, and delay. This is really bad for user experience. I would assume this is strictly related to the chrome browser not closing the socket...
I have also seen this delay when creating multiple WebSocket connections from the same browser tab in Chrome within a short period of time. I believe this is to address a potential security issue with WebSockets which would allow a browser to be hijacked to do port scanning inside a network. By limiting the number of WebSocket connections that can happen within a given amount of time, you greatly limit the utility of a browser as a remote port scanner. In addition, the amount of information that is returned by onclose and onerror is intentionally limited for the same reasons.

Increasing Google Chrome's max-connections-per-server limit to more than 6

As far as I know, at the current moment, late 2011 the max-connections-per-server limit remains 6. Please correct me if I am wrong. This is bad that we cannot fix this easily as in Firefox. As far as I know this value is hardcoded.
One of the solutions is to download the Chromium's sources and rebuild them. Is there a more easy solution?
Is there any tricky way to hack this without creating a dozen of mirror-domains?
Why I'm asking the question: My task is to create a html-javascript slideshow that will run inside a fullscreened browser, and a huge monitor is hanging on the wall. The javascript is really complicated, it preloads photos and makes a lot of ajax calls to my web services. If WIFI connection is slow, if 6 photos are loading, the AJAX calls fail, the application runs bad. I want a fast solution based, on http or browser or ubuntu tweak something else, because rebuilding the javascript app will take days.
Offtopic: do you know any other things that can be tweaked in my concrete situation?
IE is even worse with 2 connection per domain limit. But I wouldn't rely on fixing client browsers. Even if you have control over them, browsers like chrome will auto update and a future release might behave differently than you expect. I'd focus on solving the problem within your system design.
Your choices are to:
Load the images in sequence so that only 1 or 2 XHR calls are active at a time (use the success event from the previous image to check if there are more images to download and start the next request).
Use sub-domains like serverA.myphotoserver.com and serverB.myphotoserver.com. Each sub domain will have its own pool for connection limits. This means you could have 2 requests going to 5 different sub-domains if you wanted to. The downfall is that the photos will be cached according to these sub-domains. BTW, these don't need to be "mirror" domains, you can just make additional DNS pointers to the exact same website/server. This means you don't have the headache of administrating many servers, just one server with many DNS records.
I don't know that you can do it in Chrome outside of Windows -- some Googling shows that Chrome (and therefore possibly Chromium) might respond well to a certain registry hack.
However, if you're just looking for a simple solution without modifying your code base, have you considered Firefox? In the about:config you can search for "network.http.max" and there are a few values in there that are definitely worth looking at.
Also, for a device that will not be moving (i.e. it is mounted in a fixed location) you should consider not using Wi-Fi (even a Home-Plug would be a step up as far as latency / stability / dropped connections go).
BTW, HTTP 1/1 specification (RFC2616) suggests no more than 2 connections per server.
Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
There doesn't appear to be an external way to hack the behaviour of the executables.
You could modify the Chrome(ium) executables as this information is obviously compiled in. That approach brings a lot of problems with support and automatic upgrades so you probably want to avoid doing that. You also need to understand how to make the changes to the binaries which is not something most people can pick up in a few days.
If you compile your own browser you are creating a support issue for yourself as you are stuck with a specific revision. If you want to get new features and bug fixes you will have to recompile. All of this involves tracking Chrome development for bugs and build breakages - not something that a web developer should have to do.
I'd follow #BenSwayne's advice for now, but it might be worth thinking about doing some of the work outside of the client (the web browser) and putting it in a background process running on the same or different machines. This process can handle many more connections and you are just responsible for getting the data back from it. Since it is local(ish) you'll get results back quickly even with minimal connections.