Good afternoon.
I have the following code, that on submit, sends data to a PHP file, which queries multiple network nodes for health status. The problem is that the tasks take about 40 seconds to complete and during that time there is no output. I tried to use ob_flush and flush. No effect, although I have in the php portion of the code. I still see the loading message and get the complete printout once it's ready. However, flush and ob_flush works in general on my server (tested as standalone script), so that's not the issue.
In my understanding that's the jQuery/ajax call that waits for the code to execute completely before spitting out the printout. I looked through the forums and couldn't find any applicable solution, as most of them are related to "GET" request while I'm using "POST".
Can someone please point me in right direction on this? Is there a way to receive printout while the PHP is still processing the request?
JS Code
$(document).ready(function(){
$('#userForm3g').on('submit', function(e){
e.preventDefault();
e.stopImmediatePropagation();
$('#response').html("<b>Loading data...</b>");
$.ajax({
type: 'POST',
url: 'myphpfile.php',
data: $(this).serialize()
})
.done(function(data){
$('#response').html(data);
})
.fail(function() {
alert( "Posting failed." );
});
return false;
});
});
Thanks!
The problem with the approach you mentioned is that there are multiple ways that it can fail: you might forget to clear the php output buffer, or the setting might be tightly controlled for some reason, there could be a proxy or load balancer that waits for the request to complete, or it could also be the web browser (chrome used to render partial content, but they stopped doing this).
There are few answers though:
You could use partial responses (which is basically streaming on http). There's a specialized library to do this which I've used before, but I forgot its name. I wouldn't recommend this option though, if it fails it will be tough to find why.
You could use any method of long polling, including comet or sockets, but you'll need a compatible server (node.js or reactphp)
You could use a 3rd party service like Pusher or OneSignal (they also use the previous approach, but it's more integrated and reliable)
Related
Let's assume PHPFile.php return random integer(X) every 2 seconds.
Now if X == 5 I would like to show an alert (client-side).
the following code will do that job :
$(function worker(){
$.ajaxSetup ({
cache: false,
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(worker, 2000);
}
});
$.ajax({
type: "GET",
url: "PHPFile.php",
success:function(result){
if (result == 5){
alert('test');
}
};
});
Now the problem is when we call this every 2 seconds it's like destroying the memory, especially if PHPFile.php(in example) has big size data.
30 Request every one minute and its counting.
So I wondering what is the best way to update client browser if a change occur, without refreshing the browser.
Maybe it's like facebook notification system.
You might want to take a look at implementation of Long Polling with PHP or Comet with PHP.
Long polling is a variation of the traditional polling technique and
allows emulation of an information push from a server to a client.
With long polling, the client requests information from the server in
a similar way to a normal poll. However, if the server does not have
any information available for the client, instead of sending an empty
response, the server holds the request and waits for some information
to be available. Once the information becomes available (or after a
suitable timeout), a complete response is sent to the client. The
client will normally then immediately re-request information from the
server, so that the server will almost always have an available
waiting request that it can use to deliver data in response to an
event.
im creating a messaging feature that gets the latest messages from a database every few seconds, basically this method does a continuous database search in order to display new messages.
example of the code:
function getLatestActivities(){
var ignoreMessagesArr = $("input.activityId").map(function(){ return this.value; }).get().join(",");
var profileId = $("input#userActivityId").val();
$.ajax({
traditional: true,
dataType: "json",
type: "GET", url: "include/process.php",
data:{
getLatestActivity: "true",
toUser: profileId,
ignoreMessages: ignoreMessagesArr
},
success: function(data){
$.each(data, function (i, elem) {
$('.commentMessage').after(elem.value);
});
}
});
}
What I want to know is whether there is a more efficient way of performing this task, i.e. detecting a change in the database instead(???).
It sounds like you want your web app to receive data when it changes in the database, but not necessarily to send data in real time. If two way communication is required then you are looking for Web Sockets which Socket.IO will help you with server side but requires that you run a Node server. There is a Google code project that enables Web Sockets for PHP called PHPWebSocket but, if I remember right, requires that you run it in a separate process (i.e. run it from the command line). So that kind of takes care of the server part, but now you have to worry about the front-end.
Currently only FireFox and Chrome fully support Web Sockets according to CanIUse. For those browsers lacking support you need a polyfill. Here is a list of HTML5 polyfills. So Web Sockets can be sort of a mess to implement, so make sure that's what you want to do.
On the other hand if your webapp only needs to receive data then EventSource (a.k.a. Server Sent Events) is the way to go. The support is better on the front-end and you don't really have to do much on the server. Again, for less than stellar browsers you will need a polyfill, but that pretty much just means IE. See the following sites/tutorials on how to use this feature.
http://my.opera.com/WebApplications/blog/show.dml/438711
http://dsheiko.com/weblog/html5-and-server-sent-events
http://www.html5rocks.com/en/tutorials/eventsource/basics/
If none of that works there are a few options. Constant polling using some kind of repeating structure like setTimeout, long polling (a.k.a. hanging get) where the server leaves the AJAX request open until there is new data, and there's also the infinite iframe trick, or maybe even a Flash plugin that connects to the server to get data.
You might want to look into Socket.IO it's geared toward realtime communications with the server. Then you can design the backend to push data to the client when it's available rather than constantly polling the database for new information from the frontend
HTML5 Web Sockets allows for two way communication between the client and your server...
In my opinion you should request only the last ID inserted in your database and add it as a parameter to to your ajax request.
process.php should handle that ID and if there are other rows to do the search.
like
$query = mysql_query("SELECT `ID` FROM `table` WHERE `ID`>'$lastId'");
$result = mysql_num_rows(); //use that to see if you have new rows.
At the moment I’ve got one function to check, if a webpage is reachable. I’ll call this function at about 100 times in a while-loop, which means it sometime lasts 5 minutes to check all these 100 webpages.
I never before used ajax but I would think that it would be a good idea to solve this problem with ajax, but I never used ajax before and have no idea, how to start. Could you give me a good hint? Thanks for every answer!
I would use jquery-ajax, makes it simpler.
So put jquery on your site to start.
This is how jquery ajax works:
$.ajax({
type: 'POST',
url: '--LINK TO PHP/ASP...---', // Place the link that has the command
data: dataString, // dataString is a json encode of the data that is sent to the file
dataType : 'json',
beforeSend:function(){
// Before you send the info, do what you want here (ie loading gif...)
},
success:function(data){
// If it is successful, then it will do what you want here.
}
});
I hope this helps.
I would suggest you use JQuery Ajax, easier to implement.
$.ajax({
url: "test.html",
context: document.body,
success: function(){
$(this).addClass("done");
}
});
From your (somewhat ill-defined) description, I'd say that using AJAX to control the web site verification would be a deeply in-appropriate approach.
Instead, a more sensible approach would be to "batch process" the web site data via the use of a cron triggered PHP cli script.
As such, once you'd inserted the relevant domains into a database table with a "processed" flag set as false, the background script would then:
Scan the database for web pages that aren't marked as checked within your required time period.
Carry out the CURL lookup, etc.
Update the database record accordingly with the current timestamp.
...
To ensure no overlap with an existing executing batch processing script, you should only invoke the php script every five minutes from cron and (within the PHP script itself) check how long the script has been running at the start of the "scan" stage and exit if its been running for four minutes or longer. (You might want to adjust these figures, but hopefully you can see where I'm going with this.)
By using this approach, you'll be able to leave the background script running indefinitely (as it's invoked via cron, it'll automatically start after reboots, etc.) and simply add web pages to the database/review the results of processing, etc. via a separate web front end.
You could of course use AJAX to get a regular summary of the current status from the database for the purposes of client-side display.
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 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.