I'm trying to implement some push technology on an app of mine. I intend to use node.js for that but I don't think it is relevant for my question. What I will do is basically long-polling to the server, and as I understand the event driven way nodejs works, I don't have to care much about the server side of the stuff.
My only worry is on the client side: after how much time will the browser stop waiting for the answer ? It is a programming question because I need to release a response before this time is spent, so that the long-polling is reloaded.
Side question : when the browser stops waiting, what answer does it give to the request ?
I have done stuff like this before, and the answer to the question is quite simple: it depends on the browser, and how the user has configured it.
In FF there is a setting somewhere in about:config that controls this (I forget what the setting is, exactly). IE's default timeout is controlled in the registry, and is documented here. I never found the answer for Chrome or Opera - I don't think it's controllable. Opera seems to give up after no data has been received for around 20 seconds, but it also seems to vary somewhat - no idea why.
I concluded that the best thing to do here is to design your architecture so the page is reloaded periodically or if your using AJAX, periodically cancel the request and start a new one (I found that 1 minute works well). Also, keep pushing little bits of data to the browser every few seconds, as this will prevent Opera from giving up. You can simply push a javascript:void(0); event to keep the connection alive but not actually do anything at the client side.
To answer your side question: Nothing. The browser simply closes the TCP connection and no further data is exchanged. How the server handles this is no longer the concern of the browser.
Related
My server receives two GET requests when I use Ctrl+Shift+R in the browser. But when I use Ctrl+r, my server only receives 1 GET request. Why does my server receive 2 requests when using shift? (I believe using the shift key will clear cookies or something).
Google chrome sends multiple requests to fetch a page, and that's -apparently- not a bug, but a feature. And we as developers just have to deal with it.
As far as I could dig out in five minutes, chrome does that just to make the surfing faster, so if one connection gets lost, the second will take over.
I guess if the website is well developed, then it's functionality won't break by this, because multiple requests are just not new.
Have PHP/mySQL/JS-JQuery based web site that records finish times for racers, then sends the time back to the server. The server inserts the finish time in the db, Calculates the finish place based on a handicapping formula. Stores that and send the finish place back to the web page and it is updated on the screen.
It uses Jquery Ajax calls so the page doesn't get reloaded at all.
Everything works fine if the data connection is good.
If the data connection is bad my first version of this page would put a message up that the connection was bad.
Now I am trying to make it a bit smarter, so I have started with the HTML5 feature that tells the browser if it is on or offline(i realize this may not be the best way yet but it works for concept testing)
When a new finish time is recorded(or updated) and we are offline the JS just adds a class of notSent to the tag of the finish time. The finish place and all of the finish places would normally come from the sever are greyed out indicating the data is no longer valid(until it can communicate with the server).
When the browser finds itself back online, A simple jQuery each loop on each notSent class starts re-sending the AJAX requests and if they all get completed it processes the return finish place information and display it as up to date.
It also disables all external links on the page when the browser is offline. This keeps the user from losing the data entry page by accident by clicking a link that will give them a page not found button.
So my last issue, is the browsers reload and close buttons, if the user click these when it is offline they will lose the data entry screen and are out of luck until the connection comes back.
Can I disable these functions as well? A quick Stack-overflow search of this indicates it can be done but most answers give the old, "you really shouldn't and if you think you need to you should rethink your design." warning.
So rethinking my design I start learning about;
HTML 5 local storage (decide I don't need it, since my data is stored already in a input box)
App-cache Manifest for controlling the cache of the page so if reloaded in the browser off line if would get that cached version. After much reading came to the conclusion that this could work on a static page but not mine where the data is updated all the time. Then found that most browsers are deprecating this anyways.
Service Workers seems to be the possible future for contorlling offline caching, but not all browsers support it, it is pretty cumbersome to learn and still very new.
Now I am stuck, Leaning towards preventing browser reloads and defering learning service worker till more support and better examples for a dynamic content pages like mine.
Bottom line- am I missing something here? Is there a easy solution?
I think the best option is to use PouchDB to sync between the client and server and use Background Sync to awake a Service Worker when you regain connectivity. If Service Worker is not present in your browser, it can sync the next time your user open the browser.
You have a similar example of deferred requests explained in the Service Worker Cookbook,
I have a situation where a part of some code depends on fetching a value out of the ASP.NET Session State. This works fine in all major browsers, however I one client that, for whatever reason, uses the AOL web browser, and it seems to be incapable of understanding this logic.
Every time there is a call to the session state in the code, even on the server side, the page throws an exception for them. This is easily remedied by simply having them use another browser - but I am wondering, is there a way to get around this sort of behavior?
By default the session is stored in a cookie. Maybe this aol browser is blocking all type of cookies? If this is the case, maybe he can relax a little this feature or you can change the persistance to sql.
Reposted just to mark the question closed and answered
I know that there are a variety of similarly posed questions here on SO and I've had a look at the ones that are suggested as matches. However, none quite manage to solve the issue that I'm facing. Basically, I'd like to know if there's a way to 'subscribe' to an event at client level in order to have a small portion of the page rendered from the controller. I know that I can use javascript setInterval() (in combination with jquery ajax) to 'poll' the controller action in order to determine if something 'new' should be renedered onto the page. However, I'm not a huge fan of polling, especially when client browsers can be left unattended and are uneccessarily polling for changes. Multiply that by the number of potential client machines that could be browsing the app and you get a feel for the scale of the issue with this approach. Now, in truth, this is EXACTLY the approach that I use to refresh certain page fragments on some ('read' - MANY!!) of my existing sites.
However, I'd like to know what the options are for subscribing in 'reverse' to events and having the controller 'know' about the client browser and any events that it is subscribed to and the controller then 'push' out the update to the client on a 'needs must' basis. Is this something that happens outside of the normal desktop events scenario?? is the idea even scaleable or is it just the same potential bottleneck in reverse of the method that I currently use.
Hopefully, some interesting approaches out there to this double edged sword.
The server can not contact the client. The only other option besides polling is leaving an open connection between the client and server that the server can then stream info through. This is not less resource consuming than polling.
You can write a script that detects action on the client browser and goes into a "sleep" mode after a few idle minutes during which it does not poll.
Never tried it, as it seems to me that maintaining a long-running connection is a good way to run out of worker threads1 - but Comet seems to be what you're looking for.
Note that others have suggested ways around the thread per connection model.
I'm sure Wave doesn't poll the server every millisecond to find out if the other user has typed something... so how can I see what the other person is typing as they type? And without hogging the bandwidth.
Persistent HTTP, Comet
Keep your HTTP connection alive and send characters as they are typed
*Edit in 2014: also, take a look at WebSocket and HTTP/1.1 Upgrade header. Browsers started implementing this around 2010, so I'm adding this to original answer.
They probably use Web Sockets, aka server-sent events: http://www.w3.org/TR/websockets The underlying protocol can be found (as a draft) at the IETF.
Update: it doesn't seem WebSockets has any implementation yet; and a video from Google I/O (go to 11:00) talks about a long lived HTTP GET request.
Server Push in GWT
Server push is the Wait, Respond, Close, Re-Open paradigm:
Wait: When the GWT code makes a call
to your server for some data that you
don't have yet, freeze (wait)
Respond: Once the requested data is
available, respond with it
Close: Then, close the connection.
Re-Open: Once your GWT code receives the response, immediately open up a new connection to query for the next event.
See Video Google Wave: Powered by GWT around at minute 55 (near the end)
Q: How you implement the persistent Connections, the long living http connections
A: Future Plan: HTML5 Web Sockets. Longer term. That's what we use at the moment.
Q: Is there a platform or library for this we can download and play with?
A: Not sure. Don't think so
P.S.: That's what he said. To me it did not make much sense ("future plans" vs "using at the moment"). Any native english speaker might want to verify if I transcribed it correctly?
Pure speculation but could it be using the Server Side DOM events from the HTML 5 spec?
the entire reason for WebSockets is to have the browser keep a bi-directional socket open to a server so that real time communications can be used. When someone types on the other end, in a wave client, it triggers an event that is sent to the server and the server in turn looks to see who should also receive the event and pass them the event, in this case the typed letter.
WebSocket and Comet are different.
Granville
Probably comet for now websocket in the future. Because it works in Firefox 3.5 and from what I've read the websocket is only available in the nightly builds of FF... I could be wrong though... as it appears to not work in IE at all.
I spent some time reverse-engineering the Google Wave client code (shameless plug for http://antimatter15.com/misc/read/ which is a read-only public client for google wave for all public waves without need of robots or gadgets which was a lot more useful a month ago when Google didn't launch the upgrades).
Anyway, Google uses the GWT framework with certain aspects of the Google Closure library (which is actually open source and documented) and they use the goog.net.BrowserChannel library, which from the comments is also used for chat functionality within gmail.
http://closure-library.googlecode.com/svn/docs/closure_goog_net_browserchannel.js.html
I would assume that they use ajax requests. Do an XMLHttpRequest, which is asynchronous, and when the server has something to send your browser the javascript callback that was registered gets the data and does whatever with it. So basically the browser requests the next event, handles it, repeats indefinitely.