I am curious as to how Facebook pushes data to the browser as in the news feed. New data shows up at the top of the feed without reloading the page or clicking a button
Does Facebook achieve this by polling their server through AJAX at a set interval or do they somehow push new data from the server to the client unprovoked?
If so what language or API do they use to do this?
It's actually called 'long polling', or 'comet'. There are different ways to perform server push but the most common way is to keep connection open while it receives data (it has drawbacks as browser have limit of number of open connections to a host). Facebook had open-sourced the Tornado web servers, which can handle a lot of open connections (which can be a problem is you have a lot of users, but you are using apache for example). In the moment you receive AJAX response, you simply perform a new request, waiting for next response.
Essentially the code does an AJAX call to their servers, and either waits for a response which triggers another request, polls on a timer, or they open a websocket to receive data as soon as it's pushed. This of course is for "new" data showing up at the top of the feed. When the page is reached at the bottom, they just do another AJAX call to get the next n items.
They push it with AJAX, and they use (at least they USED to use), infinite scrolling.
So you'd load your page, and they'd make an initial call to the server to load some messages based on who is logged in, say with a framework like JQuery:
http://api.jquery.com/jQuery.ajax/
And then as you scroll down, they make note of when you're close to the bottom of the page and they need to load more so you're not left without data, and then they make another call automatically. This is called infinite scrolling, and keeps track of where you are in the DOM:
Just one example: http://ajaxian.com/archives/implementing-infinite-scrolling-with-jquery
Related
I am currently creating a stock market simulation and am working on the moment that the user logs into the simulation. I have a PHP script that will generate a certain price for a company four times and update it into my MySQL database while running. I currently have the following code:
PHP:
if (isset($_SESSION['userId']))
{
$isPlaying = 0;
while ($isPlaying <= 3)
{
$priceTemp = (rand(3300, 3700) / 100);
$sql = "UPDATE pricestemp SET price = $priceTemp WHERE companyName = 'Bawden';";
mysqli_query($conn, $sql);
sleep(1);
$isPlaying++;
}
echo '<h1>Welcome to the simulation</h1>';
}
I am aiming for these updates to happen in the background once the user has logged into the simulation. When refreshing my database every second, the updated prices are shown which is one of my objectives. However, what I would like it to do is still load the HTML onto the page (to say "Welcome to the simulation") while updating the database with every second with an updated price.
So far, when I log in, I have to wait 4 seconds before the HTML will load. In the future, I hope to have it consisently updating until a certain condition is met but when I have set an infinite loop earlier the HTML never loaded.
What do I have to do to allow the HTML to load once logged in and have the prices being generated and updated in the MySQL database in the background with no delay in either of these tasks happening?
You have a fundamental misunderstanding of how web-based requests work.
What you need to understand is that PHP is a server-side language. PHP generates any combination of HTML, CSS, JavaScript, JSON, or any other forms of data you want and sends it to your web browser when it's finished. While it's doing that, it can also manage data within a database or perform any other number of actions, but it will never send what the web browser can make use of until it finishes setting everything up. So if you're within an infinite loop, it will never finish and therefore nothing will be sent back to the web browser.
To remedy this, you need to use something called "asynchronous JavaScript", more commonly referred to as "ajax". Specifically, you first send some initial HTML to the web browser in one request and let the request end immediately. This allows the user to see something without waiting around for an indefinite period of time. Then, on the web browser end, you can use JavaScript to automatically send a second request to the server. During this second request to the server, you can perform your data processing and send back some data when you're finished to display to the user.
If you want to periodically update what you show the user, then you would repeat that second request to refresh what is shown on the user's webpage.
Any time you see some kind of "real-time" updating on a website, it's not coming from a single, persistently open connection to the web server--it's actually a series of repeated, broken up requests that periodically refresh what you see.
Broken down, standard web request workflows look something like this:
Web browser asks the web server for the webpage. Web browser waits for a reply.
Web server generates the webpage and sends the webpage to the web browser. Web server is done.
Web browser receives the webpage and shows it to the user. Web browser stops waiting for a reply.
Web browser runs any JavaScript it needs to run and requests data from the web server. Web browsers waits for a reply.
Web server processes the request and sends the requested data back to the web browser. Web server is done.
Web browser receives the requested data and updates the HTML on the webpage so the user can see it. Web browser stops waiting for a reply.
As you can see, each series of requests is 1) initiated by the web browser, 2) processed by the web server, and 3) any replies from the web server are then handled by the web browser after the web server is finished up. So each and every request goes browser -> server -> browser. If we add steps 7., 8., and 9. to the above, we will see them repeat the exact same pattern.
If you want to avoid adding JavaScript into the mix, preferring to refresh the entire page every time, then keep your data processing short. Optimize your database calls, fix your infrastructure (make sure your server and database have a LAN connection, that your hardware is good enough, etc.), make your code more efficient... do whatever you need to do to keep the processing time to a minimum.
This is all incredibly simplified and not 100% accurate, but should hopefully help you with your specific problem. The short version of all of this is: you can't show your HTML and process your data at the same time the way you're doing things now. You need to fundamentally change your workflow.
You have to do this in 2 network calls. The first network call should fetch the html. Then you have to use Javascript to fire another call to update your data. Once that api call returns it will update the html.
The scheduling model to manage the frequency of a background operation based on the frequency of requests at the front end is a very difficult problem. It's also a problem you don't need to solve. The data doesn't need to be changed when nobody is looking at it. You just need to store when the data was last looked at and apply greater deltas to older data.
We are making a app with php in which we want to push data to client browser same in the way in which facebook notificaiton sent by facebook. i know about commet and also have used ajax in past but ajax is not efficeint while commet programing is out of my mind.
Sample can seen at ESPNCRICINFO.COM live scorecard which is automatically pushed
by server to brwoser and than append to document without refreshing. Same app we
have to made.
Simply i need to build some code that send data to all the browser which have our webpage opened. No restrictions. Just need to send to all. So there is no need to check to whom data will be push.
I really need it urgently.
can you use JavaScript setTimeout(function name, seconds) ?
In JavaScript function you can generate .post request for some PHP script which can load messages, when the message will load, you can show it via you JavaScript. the timer will call this function for all people.
Here is the scenario:
I have a page that is logging data to MYSQL. I have another page that reads that data and allows it to be viewed. When a new piece of data is logged I would like to have the first script check and see if the viewing page is open in the browser, and if so append the newest data to the end of the view. Also - could anyone point to some info giving an overview of how PHP and the browser interact? I think I have the concept of the DOM down for javascript...but as far as PHP it just appears that once the page is sent, that's it...
You're correct in that once the PHP is sent, that's it.
There is no way to send data to a PHP page once the page is loaded. There is another slightly nastier method, but the easiest way of doing this is going to be polling the page via Ajax.
So, have a script that every 20 seconds, sends a message to another PHP script that contains the timestamp of the last MySQL log you received, then get the script to return all the data that has been set by that time.
I'm unsure how new you are to JavaScript, but the easiest way of doing that is probably using JQuery's $.ajax and encoding the new MySQL records as JSON.
No this isn't possible as you describe. The viewing page will have to poll the server for changes, either by periodically reloading itself, or by javascript / AJAX.
You are right that once the page is sent by PHP it can have no further influence. In fact the PHP execution thread on the server is killed as soon as output is complete, so the thing that generated the page no longer even exists.
To expand on Dolondro's suggestion, rather than periodically polling the server for updates, you could use Server-Sent-Events (newly supported in modern browsers).
With these, you basically just send 1 ajax request to the server, and the connection is held open. Then, the server can send updates whenever it wants. When the browser receives an event, it can add the data to the screen. Even still, the connection is held open, and the server can send additional events/updates as they occur.
W3C page:
http://dev.w3.org/html5/eventsource/
Wikipedia:
http://en.wikipedia.org/wiki/Server-sent_events
More Info:
https://www.google.com/search?ix=hcb&sourceid=chrome&ie=UTF-8&q=server+sent+events
There might be some cases that your request takes long time because
of some problems with your client internet connection or your server
connection. So since the client doesn't want to wait he clicks on the Ajax
link again which sends the request to the server again which messes up
the following:
Rendering of our website in the browser because we are giving extra
load to the browser.
What if the second request processed correctly and you showed user
the page and then comes along the error message from your first
request(saying request timed out) which loads above on the correct
content and mess up with the user reading the correct content.
I want to stop the 1st Ajax response if the Ajax function is called twice. How do I do this?
so i want to stop the 1st Ajax response if the Ajax function is called
twice
What you actually want is to prevent a second request when a first request is in progress.
For example, You may have to change the Save button to Saving..., disable it (and add a little progress wheel) to give live feedback to the user. (Facebook does this)
The key is love feedback to the user. If the user is clueless on what is going on, they are going to think nothing is happening.
You might want to check why the operation is taking long
If this is a complex/time consuming operation, like, say a report generation or a file upload, a progress bar should do
If this is because of the client's internet connection, say it up front, like Gmail: Your have a slow Internet connection and this site may be slow. Better still, provide a fallback option, with less/no Ajax.
You say cause we are giving extra load to the browser: this is kind of fishy. You will not be giving extra load to the browser unless you are giving it tons of HTML to render. Use Ajax only for small updates on the browser. You may want to reload the page if you expect a large change.
How bout seeing as your using some form of JavaScript to begin with you have that link either hidden or disabled in a manor of speaking til the pages request has been followed through with. You could for example have the requested ajax wait for a second variable that would enable that link so a user could click it. But until that variable is received from the original AJAX request its disabled to the click, then if it is clicked it disables again and waits for the same variable to come back again.
Think of how some developers disable a submit button on a form so a user can't double submit there form.. same concept of notion here.
I am developing a web app for iphone which requires the application to check for changes in a text file, and as soon as a change is detected, to complete certain actions.
The text file changes around once every 3 but the change has to be detected almost instantly and so I'm currently doing an ajax refresh every second.
This works perfectly on a desktop browser with no visible refresh noticeable, however on the iphone the activity spinner is practically constant.
Can this be suppressed? Or stopped?
N.B I'm currently using the jquery framework for ajax!
No, using the xmlhttprequest object (jquery is based on this object) is going to envoke http traffic, which will cause the spinner to load.
Try polling a little less often and see if it stops.
Also you could try using websockets, however i'm not sure if this would still affect the spinner.
http://lukeredpath.co.uk/blog/pushing-events-to-your-iphone-using-websockets-and-pusher.html
Sidenote: the spinner is there to inform your users that they're requesting traffic, imo trying to block this user feed back is bad ux.
You can't. That spinner is "warning" the user that bandwidth is being used.