I am writing an on line chat room based on AJAX/COMET. My design is:
Request
----------------- wait -------------------------> send dump data
----------------- wait -------------------------> send dump data
----------------- wait -------------------------> send dump data
----------------- wait -------------------------> send dump data
----------------- wait -------------------------> send dump data
------ something happened, get response.
Another request
.....
....
As you see, the server hold the request and wait something happened, if there is some event happened, just push data and finish request. Then the client will issuse another request.
There is tick in request, so if there is event happened betweenhe t gap of two requests, server knows that there is pending event for the client.
Before the browser timeout, the server also send some idle data to prevent client from timeout.
Now, here comes the problem: what are timeout behavior of different browsers? I know that browser sends request and wait for data, if it take too long time to wait, it will timeout. But what are those timeout behavior of different browsers? And are there any header that can control the timeout behavior of browser? By knowing the timeout behavior of browsers, so that I can decide how to deal with them. Where can I find those data?
Actually, since the client could be going through proxies, the explicit values of the timeouts for different browsers don't mean as much as you'd think.
Rather, I'd ask why you're asking - you're going to have to deal with timeouts, and no amount of streaming to the browser is going to prevent it every time. So it'd be best to simply requery the server from the client when the connection drops - which is one reason why a lot of people recommend long polling which is what you seem to be trying to do. Regardless of whether you choose a streaming solution or a long poll, you have to allow for connection resets.
For a simple hidden iframe client setup, it's not too hard to do - and it's equally easy for XHR requests, depending on what client side framework you're using.
The timeout for most modern browsers seems to be rather large in IE (60 minutes? Wow), and shorter in FF (about:config says 300 seconds - eek) - but as I said, that doesn't help you against a proxy, where the timeout could be as short as 2 minutes or less, depending on how the proxy admin configured it.
So, in summary - timeouts happen. You can't stop them. Code your client to reconnect when they happen (with a limit to prevent a spin on server down), and don't worry about it further. Besides being more robust, it'll probably also make your code more performant, since you won't be periodically pumping useless data to every client.
Related
setInterval(function(){
// ajax request here
}, 9000);
I use a script like this to check for new notifications in the database and display them back on the page, giving the fact that for every user this check will be performed every few seconds or every minute i wonder if this can cause any performance issues.
Is it ok to make so many requests to the database or should i check for new notifications some other way?
There are two things you need to consider:
How often are updates needed?
Can the server respond to them that frequently?
The first of those, only you can answer.
The second depends mostly on how much work the server has to do for each request, how many concurrent users you have, and how good the server hardware and network connection are.
The biggest risk with your current approach is that if the server can't respond that frequently, then you will have simultaneous requests in flight. If there is a real performance problem, you could end up with a queue of requests waiting to go out from the browser once you hit the maximum simultaneous HTTP request limit.
You can mitigate this risk by putting setTimeout in the success and error handlers for the request instead of sending them out every 9 seconds regardless.
An alternative approach would be to have the server initiate the sending of data when a notification became available. You could do this using WebSockets.
We would like to check every 3 seconds if there are any updates in our database, using jquery $.ajax. Technology is clear but are there any reasons why not to fire so many ajax calls? (browser, cache, performance, etc.). The web application is running for round about 10 hrs per day on every client.
We are using Firefox.
Ajax calls has implications not on client side(Browser,...) but on the server side. For example, every ajax call is a hit on server. ie. more bandwidth consumption, no of server request hit increases which in turn increases server load etc etc. Ajax call is actually meant to increase client friendliness at the cost of Server side implications.
Regards,
Ravi
You should think carefully before implementing infinite repeating AJAX calls with an arbitrary delay between them. How did you come up with 3 seconds? If you're going to be polling your server in this way, you need to reduce the frequency of requests to as low a number as possible. Here are some things to think about:
Is the data you're fetching really going to change that often?
Can your server handle a request every 3 seconds, how long does the operation take for a single request?
Could you increase the delay after inactivity or guess based on previous server responses how long the next delay should be?
Can you stop the polling completely when the window loses focus, and restart it when it's in the foreground again.
If a user opens the same page in a website 10 times, your server should recognise this and throttle its responses, either using a cookie with a unique value in it (recommended) or based on the client IP address.
Above all, instead of polling, consider using HTML 5 web sockets to "push" data to the client - most modern browsers support this. Several frameworks are available that will fall back to polling if web sockets are not available - one excellent .NET example is SignalR.
I've seen a lot of application making request each 5sec or so, for instance a remote control (web player) or a chat. So that should not be a problem for the browser to do so.
What would be a good practice is to wait an answer before making a new request, that means not firing the requests with a setInterval for instance.
(In the case the user lose its connection that would prevent opening too much connections).
Also verifying that all the calculations associated with an answer are done when receiving the next answer.
And if you have access to that in the server side, configure you server to set http headers Connection: Keep-Alive, so you won't add to much TCP overhead to each of your requests. That could speed up small requests a lot.
The last point I see is of course verifying that you server is able to answer that much request.
You are looking for any changes after each 3sec , In this way the traffic would be increased as you fetching data after short duration and continuously . It may also continuous increase the memory usage on browser side . As you need to check any update done in the database , you can go for any other alternatives like Sheepjax , Comet or SignalR . (SignalR generally broadcast the data to all users and comet needs license ) . Hope this may help you .
It's easy enough to build an Ajax app which checks all responses to make sure they aren't indicative of a session expiry, and if the session has expired automatically log the user out with a friendly "Your session timed out due to inactivity" error message.
But a common occurrence in Ajax applications is that:
User is logged in, happily using app, retrieving data over http with an established http session
User closes laptop
Host times out http session after N minutes
User reopens laptop later on. Ajax app appears alive and well. They click around which is just fine since the app lets them see things they've already loaded.
Then, they click on something that requires data to be loaded, and the data comes back indicating session expiration
The Ajax app kicks them out and says "Your session timed out due to inactivity".
This is really weird to the user because they were not inactive from their point of view.
Now, one possibility is to have Javascript code in the client which uses setTimeout() to periodically (say, every 15 minutes if the session timeout is 30 minutes) trigger a request to the host to ask how much time is left in the session. This periodic check is great because it lets you show them a warning when they are close to timing out, e.g. "You're session will time out in 1 minute unless you do something".
But that doesn't help when the user's machine is suspended. That's because according to all my testing in many different browsers, setTimeout time applies to elapsed running time instead of elapsed real time. That is, if you call setTimeout("alert('hi')",2*60*1000); and then suspend your machine 10 seconds later, wait 5 minutes, and reactivate your machine, you'll have wait 110 more seconds until you get that alert (I have not been able to find definitive documentation of this behavior but it is a demonstrable fact). So that means your period check may not happen for quite after the user's machine resumes.
My solution to this is to, instead of having my periodic check based on on a long setTimeout, instead do a short setTimeout (say, every 5 seconds), and check the elapsed time since the last check using new Date().getTime() to get the actual clock time. This way I am always checking against the real clock, and instead of the client waiting from zero to fifteen minutes before realizing it has timed out after a suspension, at most it will wait about five seconds (plus http response time) to find out.
But I dislike this solution because it relies on a frequent timer based interruption. Is there a smarter way to handle this?
With big sites like facebook, which is rich with interactive updates, you'll find that there is a combination of all sorts different mechanisms. I'd guess that they're doing validation both on API requests and on Push requests (since someone once told me they use push in addition to ajax)
Timeouts: One thing to consider is that if you store session data in a cookie, having that cookie expire is the same as no longer being logged in. Since the cookie is a hashed value of a few things like a user ID, or a timestamp, it is really easy to see that a session is no longer valid on the very first function call to the API.
Long polling: if a site uses long polling in which a connection is opened indefinitely to await a response from the web server, then closing your computer would kill that connection.
However, if they're just doing regular ajax polling with a reoccurring function call via setInterval, then the web server would automatically know whether the user should get data in return based on the timestamp in their hashed cookie, assuming there is one to check. Those are the types of things that get sent in the header.
Some services actually update a database field that stores your timestamp of last activity and then expires if a certain amount of time has elapsed. This is a less efficient way to do it since it keep track of state.
There's really quite a few ways sites do these things.
On a site like Trello.com, I noticed in firebug console that it makes frequent and periodic Ajax POST calls to its server to retrieve new data from the database and update the dom as and when something new is available.
On the other hand, something like Facebook notifications seem to be implementing a COMET push mechanism.
What's the advantage and disadvantage of each approach and specifically, my question is why Trello.com uses a "pull" mechanism as I have always thought using such an approach (especially since it pings its server so frequently) as it seems like it is not a scalable solution - when more and more users sign up to use its services?
Short Answer to Your Question
Your gut instinct is correct. Long-polling (aka comet) will be more efficient than straight up polling. And when available, websockets will be more efficient than long-polling. So why some companies use the "pull polling" is quite simply: they are out of date and need to put some time into updating their code base!
Comparing Polling, Long-Polling (comet) and WebSockets
With traditional polling you will make the same request repeatedly, often parsing the response as JSON or stuffing the results into a DOM container as content. The frequency of this polling is not in any way tied to the frequency of the data updates. For example you could choose to poll every 3 seconds for new data, but maybe the data stays the same for 30 seconds at a time? In that case you are wasting HTTP requests, bandwidth, and server resources to process many totally useless HTTP requests (the 9 repeats of the same data before anything has actually changed).
With long polling (aka comet), we significantly reduce the waste. When your request goes out for the updated data, the server accepts the request but doesn't respond if there is no new changes, instead it holds the request open for 10, 20, 30, or 60 seconds or until some new data is ready and it can respond. Eventually the request will either timeout or the server will respond with an update. The idea here is that you won't be repeating the same data so often like in the 3 second polling above, but you still get very fast notification of new data as there is likely already an open request just waiting for the server to respond to.
You'll notice that long polling reduced the waste considerably, but there will still be the chance for some waste. 30-60 seconds is a common timeout period for long polling as many routers and gateways will shutdown hanging connections beyond that time anyway. So what if your data is actually changed every 15 minutes? Polling every 3 seconds would be horribly inefficient, but long-polling with timeouts at 60 seconds would still have some wasted round trips to the server.
Websockets is the next technology advancement that will allow a browser to open a connection with the server and keep it open for as long as it wants and deliver multiple messages or chunks of data via the same open websocket. The server can then send down updates exactly when new data is ready. The websocket connection is already established and waiting for data, so it is quick and efficient.
Reality Check
The problem is that Websockets is still in its infancy. Only the very latest generation of browsers support it, if at all. The spec hasn't been fully ratified as of this posting, so implementations can vary from browser to browser. And of course your visitors may be using browsers a few years old. So unless you can control what browsers your visitors are using (say corporate intranet where IT can dictate the software on the workstations) you'll need a mechanism to abstract away this transport layer so that your code can use the best technique available for that particular visitor's browser.
There are other benefits to having an abstracted communications layer. For example what if you had 3 grid controls on your page all pull polling every 3 seconds, see the mess this would be? Now rolling your own long-polling implementation can clean this up some, but it would be even cooler if you aggregated the updates for all 3 of these tables into one long-polling request. That will again cut down on waste. If you have a small project, again you could roll your own, but there is a standard Bayeux Protocol that many server push implementations follow. The Bayeux protocol automatically aggregates messages for delivery and then segregates messages out by "channel" (an arbitrary path-like string you as a developer use to direct your messages). Clients can listen on channels, and you can publish data on channels, the messages will get to all clients listening on the channel(s) you published to.
The number of server side server push tool kits available is growing quite fast these days as Push technology is becoming the next big thing. There are probably 20 or more working implementations of server push out there. Do your own search for "{Your favorite platform} comet implementation" as it will continue to change every few months I'm sure (and has been covered on stackoverflow before).
Okay, I know it sounds generic. But I mean on an AJAX level. I've tried using Firebug to track the NET connections and posts and it's a mystery. Does anyone know how they do the instant autosave constantly without DESTROYING the network / browser?
My guess (and this is only a guess) is that google uses a PUSH service. This seems like the most viable option given their chat client (which is also integrated within the window) also uses this to delivery "real time" messages with minimal latency.
I'm betting they have a whole setup that manages everything connection related and send flags to trigger specific elements. You won't see connection trigers because the initial page visit establishes the connection then just hangs on the entire duration you have the page open. e.g.
You visit the page
The browser established a connection to [example]api.docs.google.com[/example] and remains open
The client-side code then sends various commands and receives an assortment of responses.
These commands are sent back and forth until you either:
Lose the connection (timeout, etc.) in which case it's re-established
The browser window is closed
Example of, how I see, a typical communication:
SERVER: CLIENT:
------- -------
DOC_FETCH mydocument.doc
DOC_CONTENT mydocument.doc 15616 ...
DOC_AUTOSAVE mydocument.doc 24335 ...
IM collaboratorName Hi Joe!
IM_OK collaboratorName OK
AUTOSAVE_OK mydocument.doc OK
Where the DOC_FETCH command is saying I want the data. The server replies with the corresponding DOC_CONTENT <docname> <length> <contents>. Then the client triggers DOC_AUTOSAVE <docname> <length> <content>. Given the number of potential simultaneous requests, I would bet they keep the "context" in the requests/responses so after something is sent it can be matched up. In this example, it knows the IM_OK matches the second request (IM), and the AUTOSAVE_OK matches the first request (AUTOSAVE)--Something like how AOL's IM protocol works.
Again, this is only a guess.
--
To prove this, use something like ethereal and see if you can see the information transferring in the background.