Synchronize Ajax response - php

I'm in a codeigniter environment and I want to do something like this.
There is a chatroom with a single O-wner and some C-lients.
This is what I'm trying to write
1) C joins the room.
2) when ready, all Cs clicks on a "ready" link that sends an ajax request
3) C waits for all the Cs to get ready, then signals all client and the previous ajax reponses are sent
4) when C receive the response (which should be in the same moments for all the clients) they start doing what-they-have-to-do :)
Is there an easy way to keep track of all the clients connected so that I can signal them all simultaneously?
For now I'm stuck at step 3. I have a code like this
$.ajax({
url: 'myurl.php',
success: function() { doStuff(); }
});
and in my hypotethic file myurl.php i have
while ($this -> MyModel -> waitingQueue) {
sleep(1) }
return "ok";
I guess this is not a good approach since I can't control whether all the clients receive the responses in the very same instane, when I change in my model the variable "waitingQueue".
Thanks all!

You can try to mimic synchronisation with a regular ajax check from all clients on a server. Check the jQuery.queue function, start a queue polling with SetInterval, and then push function containg the checks in that queue (and in theses functions flush the queue).
If you want to go one step further you should get a look at 'Comet' and persitent HTTP connections, trying to put PUSH behavior in HTTP, but it won't be simple :-) At least if you get the complete control of your network, server, people connecting to your app (like an intranet) it will be simplier.
Or you can check documentations on the now closed project google waves.

i recommend using setInterval() in javascript. so you can check continuously for server state.
i don't think you can synchronize your clients that simple. and they will not get the answer from the server at the same time.
if you synchronize the watches of all clients and arrange a collective point in time, when the client shell trigger an event, you might get a good chance.
...and don't forget clearInterval()

Related

continuebrowsing without waiting output to php

I currently submit a process to a class.php page doing some calculations, which get written to a MySql database for the users to use.
Depending on the clients internet speed the calculation do take long and the user is waiting for it to finish.
Is there a way to submit the process and allow the users to continue browsing while it finish in the background.
The calculation only need to be submitted once a week
I have
rank.php
inside it $ranklist=$admin->do_ranking()
then inside admin.class
function do-ranking(){
the calculations
}
return $ranking
}
There are two wide spread strategies for this:
send response early and detach
You can send the response (whatever that is, might also be empty) right away and forward the task to be computed to a background task. Several options for that, either based on a cron task periodically checking for waiting jobs to be computed. So we are talking about a simple job scheduler, you will find easy examples for that. Or you can spawn a system process and detach from that. how exactly depends on the operating system you use, on Linux for example you can push the process into background, thus return immediately to the spawning php script.
use a ajax request to transmit the data
This certainly is the much more elegant approach: instead of doing a full page reload at all (by sending a form form example) you use some simple client side logic (read: javascript) to send the data (or an empty request) via an ajax request. That means the page loaded into the browser is not unloaded at all and the user can do whatever he likes.

Determinate update time

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. :)

Whats an alternative way of updating a page with new records as they are inserted into a table automatically without using jquery/ajax

I've wrote a small chat system using jquery, php, and mysql; however, I'm looking for some kind of technology that will only update a if a new record is inserted into a row. I feel like using jquery ajax calls every second to retrieve new records is really overkill and strenuous on my server.
You are looking for a Comet solution: http://en.wikipedia.org/wiki/Comet_%28programming%29
The idea, as pdr noted, is to the javascript continuously open an async request with the server. The server holds it open, but does not send anything until it determines there is something to send. The request will timeout on the javascript side after 10-20 seconds, after which it should re-open the connection.
This uses a 'subscriber' based model, by which the server will send out the chat message or what have you, to all clients which are subscribed, all at once. This saves you many database requests, as the server is the one asking for the requests, not the individual clients.
What you want is long polling. Basically, you make an XHR, and the server and PHP holdes the request open until new data is ready to be sent back.
You need to configure Apache not to timeout in this circumstances, so do some substantial research. Basically, the PHP looks like so...
set_time_limit(0);
while (TRUE) {
$db->query('SELECT `message` FROM `messages` WHERE `new` = TRUE');
if ($db) {
echo json_encode($db->results());
exit;
}
sleep(1);
}
Then, you make an XHR for this page, and it will stay open until new data is ready. Then, on the complete callback, update your page's state and make a new XHR.
This is a lot more efficient than polling for updates continually using XHR.
Make sure you do a lot of research because I believe Apache is going to think things are wrong if a PHP script hasn't stopped after 30 seconds or so. :)
There are a couple routes I know of that you can take.
Long polling. This is where the browser opens a connection to the server and does nothing until the server responds. Once the server responds or times-out (sends an empty response to the browser), a new long-polling request is made.
When going this route, you should use a server that does not rely on using a new thread for each request.
Web sockets. Again, you'll want a server that can handle requests without spawning a new thread every request. With web sockets, a connection is kept open between the client and servier, and unlike Long polling, doesn't time out. However, this isn't well-supported yet.
I highly recommend checking out http://socket.io/
The point of Ajax is that it's asynchronous. Can you not just wait at the server until there's a worthwhile response to send?
With standard HTML/CSS/JS, that's pretty much the only way since the browser can make requests of the server, not vice versa. The AJAX call shouldn't have to be very big at all. A chat system, by definition, is going to require hitting the server a lot.

I need an example of comet refresh html when database is updated!

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.

php asynchronous call and getting response from the background job

I have done some google search on this topic and couldn't find the answer to my question.
What I want to achieve is the following:
the client make an asynchronous call to a function in the server
the server runs that function in the background (because that function is time consuming), and the client is not hanging in the meantime
the client constantly make a call to the server requesting the status of the background job
Can you please give me some advices on resolving my issue?
Thank you very much! ^-^
You are not specifying what language the asynchronous call is in, but I'm assuming PHP on both ends.
I think the most elegant way would be this:
HTML page loads, defines a random key for the operation (e.g. using rand() or an already available session ID [be careful though that the same user could be starting two operations])
HTML page makes Ajax call to PHP script to start_process.php
start_process.php executes exec /path/to/scriptname.php to start the process; see the User Contributed Notes on exec() on suggestions how to start a process in the background. Which one is the right for you, depends mainly on your OS.
long_process.php frequently writes its status into a status file, named after the random key that your Ajax page generated
HTML page makes frequent calls to show_status.php that reads out the status file, and returns the progress.
Have a google for long running php processes (be warned that there's a lot of bad advice out there on the topic - including the note referred to by Pekka - this will work on Microsoft but will fail in unpredicatable ways on anything else).
You could develop a service which responds to requests over a socket (your client would use fsockopen to connect) - some simple ways of acheiving this would be to use Aleksey Zapparov's Socket server (http://www.phpclasses.org/browse/package/5758.html) which handles requests coming in via a socket however since this runs as a single thread it may not be very appropriate for something which requiers a lot of processing. ALternatively, if you are using a non-Microsoft system then yo could hang your script off [x]inetd however, you'll need to do some clever stuff to prevent it terminating when the client disconnects.
To keep the thing running after your client disconnects then the PHP code must be running from the standalone PHP executable (not via the webserver) Spawn a process in a new process group (see posix_setsid() and pcntl_fork()). To enable the client to come back and check on progress, the easiest way to achieve this is to configure the server to write out its status to somewhere the client can read.
C.
Ajax call run method longRunningMethod() and get back an idendifier (e.g an id)
Server runs the method, and sets key in e.g. sharedmem
Client calls checkTask(id)
server lookup the key in sharedmem and check for ready status
[repeat 3 & 4 until 5 is finished]
longRunningMethod is finished and sets state to finished in sharedmem.
All Ajax calls are per definition asynchronous.
You could (although not a strictly necessary step) use AJAX to instantiate the call, and the script could then create a reference to the status of the background job in shared memory (or even a temporary entry in an SQL table, or even a temp file), in the form of a unique job id.
The script could then kick off your background process and immediately return the job ID to the client.
The client could then call the server repeatedly (via another AJAX interface, for example) to query the status of the job, e.g. "in progress", "complete".
If the background process to be executed is itself written in PHP (e.g. a command line PHP script) then you could pass the job id to it and it could provide meaningful progress updates back to the client (by writing to the same shared memory area, or database table).
If the process to executed it's not itself written in PHP then I suggest wrapping it in a command line PHP script so that it can monitor when the process being executed has finished running (and check the output to see if was successful) and update the status entry for that task appropriately.
Note: Using shared memory for this is best practice, but may not be available if you are using shared hosting, for example. Don't forget you want to have a means to clean up old status entries, so I would store "started_on"/"completed_on" timestamps values for each one, and have it delete entries for stale data (e.g. that have a completed_on timestamp of more than X minutes - and, ideally, that also checks for jobs that started some time ago but were never marked as completed and raises an alert about them).

Categories