I am wondering if anyone could show, or explain with examples, how facebook checks its database for new messages? It seems to do it periodically, without loading the page. What would be the best way to achieve this in a PHP/MySQL/Jquery script?
Any help is always appreciated!
Cheers, Lea
you can do this: usign periodical updater
<span id="inbox-title"></span>
<script>
$.PeriodicalUpdater('/path/to/service', {
method: 'get', // method; get or post
minTimeout: 1000, // starting value for the timeout in milliseconds
maxTimeout: 8000, // maximum length of time between requests
}, function(data) {
$('#inbox-title').html('you have ' + data + 'new messages');
});
</script>
another option is to bind the onmousemove event and make the ajax call when than happes
There is actually a "page load", but it's a hidden request that doesn't reload the displayed page. Take a look at the jQuery Ajax command documentation for more details on one of the simplest ways to accomplish this (especially since you already mentioned using jQuery).
Have a look into reverse ajax with the COMET technique, this is a perfect use for it.
The idea behind it is to start an ajax request and let it timeout which could be 60 seconds, when it times out, start it again, here the browser has a (nearly) persistent connection to the server, if (for a simple example) a message gets created for a user. the server can reply to one of the hanging ajax requests that have been made (in this case by the recipient of the message).
No data is transfered while the xmlhttprequest and the server are waiting, but closing and reopening connections might be a burden on your server.
Related
As I'm currently in the process of making a forum system which is loading new posts/edits without having to refresh the page. Now, for the older browers which don't have an implentation of EventSource/WebSocket, I'd like to offer another option:
Every X seconds I'm GET'ing a PHP site which is echoing the five latest news. Afterwards, I'm simply checking which of those news weren't seen by the client yet and applying the changes to the page.
Now, my problem is: How would you determinate the X interval in which the client is retrieving new updates? I'd like to base it up the user's connections so that it isn't killing off his connection completely.
What would be your attempt at accomplishing this?
I would use long polling technique through AJAX in your case:
1) The client sends the AJAX HTTP-request to the server.
2) If there is an available data, server sends HTTP-request to client, otherwise instead of sending an empty response immediately, server holds the request and waits for information to become available (or for a suitable timeout event - for example, in every 25 seconds), after which a complete response is finally sent to the client.
3) After recieving the HTTP-respose, client immediately sends other HTTP-request to server.
I would do the following (code not tested, but you should get the idea). Use jQuery for simpler code.
function refreshNews() {
$.ajax({
url: "ajax-url"
}).done(function(data){
/** add code here */
setTimeout(function(){ refreshNews(); }, 30000); // 30 secs should be enough to read some headlines
});
}
refreshNews();
This way the refreshNews() function is only called after the data is received and shown to the user.
Just an idea: make a HTTP request and see how much it will take long and use it as the base! I'd repeat it, let say each 10 minutes to show how much I'm thinking about my clients!
I think it will be more resource-friendly on the server-side comparing to the long polling, especially for scripts like forums where people won't left the page for less than 10 hours. :)
I created a ajax chat application something like this to check & get messages every second. and it works fine.
function get_messages(user_id) {
$.ajax({
type : "POST",
url : "messages/get_messages",
cache : false,
data : {
user_id : user_id
},
success : function(data) {
if(data != '') {
var obj = $.parseJSON(data);
var messages = obj.messages;
}
}
});
setTimeout(function() { get_messages(user_id) }, 1000);
}
My question is, When lot of people use this application a lot to Ajax requests to server every second, is there any performance issue or server issue in doing like this, . What is the best practice for doing this ??
Thank you for your valuable suggestions :)
The best way to do chats like this is having the "chat window" properly said as an <iframe> with a permanent connection to a script that will remain running and feeding the client with the new messages so you don't have to overwhelm the server with AJAX requests. This can be achieved by calling a ob_flush() (just to make sure) and flush() after printing new stuff, causing the client to receive the updates immediately. But first you have to prepare the PHP to behave properly by doing some settings:
ini_set('zlib.output_compression', 'off');
ini_set('output_buffering', 'off');
set_time_limit(0);
If you are going to use sessions, don't forget sessions are locked to prevent concurrent writes, so after gathering the information you need from $_SESSION you must release the session by using session_write_close() otherwise the user will be unable to post messages etc.
Your script should also check for inactivity and output something to the client if the chat window remain idle for more than a couple minutes. It prevents the connection from being terminated by the browser. It doesn't have to be anything visual, something commented like <!-- keep alive --> will do.
Now, where you gonna get the new messages from? There are a couple options for doing that:
Sockets. You can have this Chat Server application running in server-side that all the Chat Window PHP scripts will connect to to be fed with the new chat lines. When a user submit a new message, its sent to the Chat Server and it broadcast to the Chat Window scripts. This Chat Server can safely be written in PHP too!
A file. The easiest way. Every Chat Window PHP script open this same file for read-only, and fseek() to its end. Loops checking if its !feof() a couple times per second to read the new lines from it, if theres any. When a user send a new message you just have append this message to the file and the trick is done.
SQL. Not recommended because every Chat Window PHP script will open a new connection to the RDBMS and eventually will reach its limit, but you can try SQLite that don't use RDBMS.
Using regular Ajax/Php for this task is not preferable. As you stated that what if there is alot of users, each user will query the database every second.
This puts too much overload on your server and the users will not have realtime communication with each other.
I would suggest you to use node.js for this task. To make it cross-browser compatible you need to use a framework of node.js which is socket.io
So the final verdict, use node.js
You can learn node.js
http://www.nodebeginner.org/
There are very good tutorials in the web.
lynda.com has also very good tutorial on node.js
People,
I am developing a web page that need to be refresh everytime that the data base gets an update. I already have the checkDatabaseUpdate() done in my PHP code.
But now I reaaly need some help to develop a simple comet to wait for a response, and another to check for update.
Is there anybody with any simple example to help me?
Is comet the right solution for that?
Thanks,
What you want to say is that on the database are executed querys (INSERT, UPDATE, DELETE) in the backend and you want to refresh the front page of a user when that query`s are executed ?
Hmm .. use a jQuery (looping) to "Ajax check" for database update in the frontcontroller and then refresh.
function refreshPage () {
$.load('checkModifDb.php', function(response, status) {
if .... { do the trick here - check jquery load.api }
}
});
and then use setInterval( "refreshPage()", 10000 ); to run the function every 10 seconds and
refresh only if it founds that db was modified.
I can't think of anything right now but i guess with little modification you shoul do the trick. This is how twitter.com do it.
Is comet the right solution for that?
Because of the way that PHP works (having a web server daemon process incoming requests), combining it with long-polling techniques can make for an unhappy server. Each connected user is going to hold open a connection to the web server daemon. Depending on that daemon's configuration, you may find that comet is an effective denial of service attack against your own server.
You'd probably be better off with plain old short-lived ajax polling here.
I am wondering how I would get data from a MySQL database and display it in real time using PHP. Without having to refresh the page. Thanks!
Use AJAX (I suggest using the jQuery library for this), and have your AJAX script (written in PHP) query the MySQL database.
You can use Socket.Io for more Speed ,efficiency and performance for Your Server
http://socket.io/
But you need Node.Js for that
You will have to use javascript. You can use setInterval(function, n) to fire your update calls every n milliseconds, and a library like jQuery to handle the ajax call and updating your page.
Download jQuery or link to a CDN hosted version of jQuery in your page. Then put something like this on your page:
setInterval(function(){
// inside here, set any data that you need to send to the server
var some_serialized_data = jQuery('form.my_form').serialize();
// then fire off an ajax call
jQuery.ajax({
url: '/yourPhpScriptForUpdatingData.php',
success: function(response){
// put some javascript here to do something with the
// data that is returned with a successful ajax response,
// as available in the 'response' param available,
// inside this function, for example:
$('#my_html_element').html(response);
},
data: some_serialized_data
});
}, 1000);
// the '1000' above is the number of milliseconds to wait before running
// the callback again: thus this script will call your server and update
// the page every second.
Read the jquery docs under 'ajax' to understand the jQuery.ajax() call, and read about 'selection' and 'manipulation' if you don't understand how to update the html page with the results from your ajax call.
The other way to continuously update your page is to use a persistent connection, like web sockets (not currently supported across all the common browser platforms) or a comet-style server-push setup. Try googling comet and/or web sockets for more info, but I think the above method is going to be much easier to implement.
I am using javascript to run a XMLHttpRequest to a PHP script which returns data. Basically I want to be able to provide the user with a progress bar (instead of a spinning circle or something) that shows the progress of getting and receiving the data. I know if I was getting a file, I could just check the content length header and use that, but in the case of a script, you don't know how much data it's retrieving.
The answer to this might be as easy as, "it's not possible," because right now it seems that way. But in conclusion: How do you monitor progress of a running script (php) over and XMLHttpRequest?
If you're using FireFox (and I'm fairly sure most other browsers other than IE), then there is indeed a way to report how much data has been transferred during an XHR operation. If the operation in question sends the correct header, it's fairly easy to use this information to calculate the percentage of the data downloaded.
I wrote this code for determining the percentage of data transferred in an XHR operation years ago, so I apologize for it not reflecting the years of coding experience I've gained since. I almost certainly wouldn't write it this way now! Still, I managed to fish it out, and hope it's of use for you.
At the time this was written, IE7 was the latest version of Explorer available, and I remember the code didn't work in that, hence it contains code to prevent it initializing under IE. I've never tried this code out under version 8 or the beta of version 9, and it may indeed work in those versions as well, but I can't vouch for it. If you can get it working in a new version of IE, please let me know!
It works by running code in beforeSend (a callback jQuery provides for code you want to run before starting an ajax request) to set up a Javascript interval (in the code I've put 50 miliseconds, which is probably far too often. 200 miliseconds should still be plenty, and put less strain on the system). Every time the interval timer fires, it runs a function that looks at the responseText attribute of the XHR request. The responseText attribute holds the raw text of the data received thus far. By counting how many characters are in there with the length() string method, we can work out how many bytes have been collected so far.
As far as working out the percentage of total data to be sent, this will require that your server side code sends a content-length header with an accurate count of how many bytes it is going to send. This will require a little cleverness on your part, but shouldn't prove too difficult. If you send an accurate content-length header, then it is used to calculate a percentage of data received so far. If you don't set a content header, then the amount of data received so far is displayed instead.
<script type="text/javascript">
$.ajax ({
beforeSend : function (thisXHR)
{
// IE doesn't support responseText access in interactive mode
if (!$.browser.msie)
{
myTrigger = setInterval (function ()
{
if (thisXHR.readyState > 2)
// When there is partial data available use it to determine how much of the document is downloaded
{
var dlBytes = thisXHR.responseText.length;
if (totalBytes == -1)
totalBytes = thisXHR.getResponseHeader ('Content-length');
(totalBytes > 0)?
$('#progress').html (Math.round ((dlBytes / totalBytes) * 100) + "%"):
$('#progress').html (Math.round (dlBytes / 1024) + "K");
}
}, 50); // Check the status every 50 miliseconds
}
},
complete : function ()
{
// Kill the download progress polling timer
if (myTrigger)
clearInterval (myTrigger);
}
});
</script>
Off the top of my head you could use 2 ajax requests. One to start and wait for the job to complete, and another to check on the job progress. I'm pretty sure most browsers can do at least 2 ajax requests at a time.
The PHP script (Lets call it job.php) that's actually doing the job can update the session variable $_SESSION['job_progress'] with the percentage the job is complete.
You have another PHP script (Lets call it progress.php) that echos that value, i.e.
<?php echo $_SESSION['job_progress'];
Client side you fire off your ajax request to job.php. You have another ajax request to progress.php that runs every 3 seconds. You update your progress bar with the value returned.
You could also do this with one ajax request if the request to job.php returns before the job is finished. Then you can keep using a single ajax request to ping the progress.php script.
In some browsers (firefox for one), onreadystatechange with readyState 3 (i.e. loading) is invoked mutiple times so download progress could be monitored.
Also, in some browsers the responseText property contains the result returns so far, and it could be examined to get some idea of the progress.
However, Internet Explorer (at least for IE7, not sure about later) does not support this, and it is an error to query responseText or responseBody for readyState 3. I have also heard the IE only calls onreadystatechange once with readyState 3 which would make it pretty useless for your purpose, but I would suggest testing it out.
Create a session. (Probably, you already have one).
Create a UID for the query, when you request it to start processing.
Store somewhere on the server (in database, in file, etc) a progress together with the SID+UID, as the query progresses.
Use a second ajax request with timer to poll the progress by SID+UID.
*You can get by only UID, probably, but I've found it to be more manageable when you also could monitor tasks by user/session.