У меня в настоящее время есть основанный на Ajax чат, который я пытаюсь оптимизировать, только загружая сценарий чата, когда обновление происходит. Таким образом ничто не должно продолжать загружаться, если ничто не изменилось в базе данных.
Моя текущая логика говорит:
setInterval()
)Если ничто не изменилось, тем не менее, это кажется довольно неэффективным, чтобы продолжать называть его. Вместо этого что я хотел бы сделать:
Как я пошел бы об этом, хотя? Функция, которую я в настоящее время использую:
function updateShouts() {
$('#chatArea').load('chat.php'); // load chat logs
}
setInterval("updateShouts()", 500); // call function every half a second
Один относительно простой способ сделать это - использовать AJAX для получения страницы, которая просто сообщает вам, было ли обновление. Так, например, вы можете получить страницу типа checkForUpdate.php
, на которой есть 1 или 0, чтобы указать, есть ли что-нибудь новое в чате. Если вы получили 1 ответ, вы можете загрузить полную страницу chat.php
.
(Если вы раньше не использовали AJAX, это довольно хороший учебник: http://www.tizag.com/ajaxTutorial/ )
Другое решение (и, как мне кажется, вероятно, лучше) - это загрузить страницу, на которой есть только самые последние строки чата. Например, предположим, что вы в настоящее время отображаете строки 1–14 чата. Затем вы можете использовать AJAX для получения содержимого, например, getLines.php? S = 14
. На этой странице будут отображаться только строки чата после строки 14. Затем вы просто добавите эти строки в конец текущего окна чата.
Я бы передавал метку времени
s (или message_id
s) вместе с любыми сообщениями чата, которые серверный скрипт посылает клиенту. Затем клиент просто запрашивает новые сообщения, а сервер отправляет только новые.
Итак, представьте, что каждое сообщение чата имеет свой ID. Я бы разработал свой chat.php
, чтобы он принимал такой параметр:
chat.php?since=12345
12345
- это id
последнего сообщения, которое видел клиент. chat.php
по сути делает что-то вроде:
SELECT * FROM chatmessages WHERE id > $since
... и передает обратно небольшую структуру данных (массив объектов, закодированных в JSON, скажем).
Таким образом, если нет новых сообщений в чате, сервер просто передает обратно пустой массив.
Я не думаю, что вы можете быть более эффективными, чем это.
EDIT:
Я понимаю, что такой способ требует немного больше кодирования на стороне клиента. Вы больше не просто обновляете некоторый div со всей историей чата. Вам также потребуется обработчик ajax-вызова, который будет перебирать результаты и для каждого сообщения программно создавать div
для этой строки, а затем добавлять его в div
чата.
Как вы знаете, функция .load заполняет элемент с выводом, возвращаемым вашим файлом chat.php. Эта функция .load выполняет два шага: она делает запрос ajax к chat.php, а затем устанавливает значение элемента для вывода chat.php. То, что вы хотите сделать, - это лишь первый шаг. Для этого используйте функцию .ajax
http://api.jquery.com/jQuery.ajax/
Вместо использования файла chat.php я бы предложил вызвать другой сценарий, например isChatUpdated.php. Этот скрипт будет действовать так же, как следует из названия, и проверять, были ли какие-либо изменения в чате. Затем вы можете использовать этот результат, чтобы выяснить, нужно ли вам вызывать функцию .load.
Сначала я бы создал файл с именем, например, messages.php, который выглядел бы примерно так:
<?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);
Затем на стороне клиента, используя jQuery или что-то в этом роде, я бы сделал что-то вроде этого:
$. Post ('messages.php', new_messages_handler)
$. Post ('messages.php', {Since: latest_datetime_we_have}, new_messages_handler)
По крайней мере, это работает хорошо красиво в голове: p
В любом случае вам нужно запросить базу данных на стороне сервера, поэтому почти не имеет значения, возвращает ли она данные журнала или одно значение.
Вы можете решить не обновлять #chatArea на основе возвращаемого значения, но в противном случае вам придется сделать еще один вызов для получения журналов.