I currently have an Ajax-based chat, which I am trying to streamline by only loading the chat script when an update occurs. Thus, nothing needs to keep loading if nothing has changed in the database.
My current logic says:
- JavaScript function fires every 1/2 second to get chat logs (
开发者_如何学运维setInterval()
)
If nothing has changed, though, it seems fairly inefficient to keep calling it. Instead, what I'd like to do is:
- JavaScript function checks if there are any new logs in the database
- If YES - load the new logs, if NO - leave the currently displayed logs alone.
How would I go about this, though? The function I am currently using is:
function updateShouts() {
$('#chatArea').load('chat.php'); // load chat logs
}
setInterval("updateShouts()", 500); // call function every half a second
I would pass timestamp
s (or message_id
s) along with any chat messages that the server-side script sends to a client. Then the client simply asks for new messages, and the server sends only what's new.
So, imagine that each chat message has an ID. I'd design my chat.php
to accept a parameter like so:
chat.php?since=12345
12345
would be the id
of the last message the client has seen. chat.php
essentially does something like:
SELECT * FROM chatmessages WHERE id > $since
... and passes back a nice little data structure (an array of objects, encoded in JSON, let's say).
So, if there are no new chat messages, the server is just passing back an empty array.
I don't think you can be any more efficient than that.
EDIT:
I realize that doing it this way requires a little more client-side coding. You're no longer just updating some div with the whole chat history. You'll also need to have a handler on your ajax call that iterates over the results, and for each message, programatically construct a div
for that line, then appends it to your chat div
.
One relatively simple way to do this is to use AJAX to fetch a page that simply tells you if there has been any update. So for example, you could fetch a page like checkForUpdate.php
that has a 1 or a 0 to indicate if there is anything new in the chat. If you got a 1 back, you could go ahead and load the full chat.php
page.
(If you haven't used AJAX before, this is a pretty good tutorial: http://www.tizag.com/ajaxTutorial/)
Another solution (and one that I think is probably better) is to load a page that only has the most recent chat lines. For example, say you are currently displaying lines 1-14 of the chat. You could then use AJAX to fetch the content of, for example, getLines.php?s=14
. This page would only display the lines of the chat after line 14. You would then just append those lines to the end of the current chat window.
As you know the .load function fills an element with the output returned by your chat.php file. This .load function does two steps: It makes an ajax request to the chat.php and then sets the value of the element to the output of chat.php. What you want to do is just the first step. To do this use the .ajax function
http://api.jquery.com/jQuery.ajax/
Instead of using the chat.php file I would suggest calling a different script like isChatUpdated.php. That script will do just like the name suggests and check if there has been any changes in the chat. You can then use that result to figure out whether you need to call your .load function.
Either way you need to query the db in the server side, so is almost irrelevant if it returns log data or a single value.
You can decide not to update #chatArea, based on a return value, but you have to make another call to retrieve the logs, otherwise.
I would first create a file called for example messages.php that looked something like this:
<?php header('Content-Type: application/json');
$messages_since = !empty($_POST['since'])
? mysql_real_escape($_POST['since'])
: '0000-00-00 00:00:00');
// Get all messages from database since the $messages_since date_time
echo json_encode($array_with_messages);
Then on the client side using jQuery or something like that I would do something like this:
- Get messages using something like
$.post('messages.php', new_messages_handler)
- In the handler I would create html for each new message we got back and append/prepend it to the chat container as well as store what time the latest message was created.
- Wait a while
- Get new messages using something like
$.post('messages.php', {since: latest_datetime_we_have}, new_messages_handler)
- Go to 2
At least it works pretty nicely in my head :p
精彩评论