Статьи

Легкий Ajax с jQuery

Пример 2 — чат с jQuery

Чтобы продемонстрировать истинную силу jQuery, мы собираемся создать полнофункциональное приложение для чата Ajax. Это позволит пользователям публиковать сообщения и автоматически обновляться — все без обновления страницы. Поскольку сейчас мы имеем дело с немного более сложным приложением, я также познакомлю вас с jQuery и продемонстрирую другие полезные функции.

Сначала мы спланируем приложение. Нам не нужно много для этого приложения — интерфейс, серверная часть и библиотека jQuery. Тем не менее, будет достаточно кода для задней и передней частей приложения, поэтому наш базовый план даст вам знать, чего ожидать от системы.

Планирование на стороне сервера

Серверная часть нашего приложения должна обрабатывать отправку сообщений и выводить сообщения. Имея это в виду, давайте составим грубый набросок внутреннего кода:

  • подключиться к базе данных
  • если сообщение было отправлено
  • вставить сообщение в базу данных
  • удалить старые сообщения
  • извлекать сообщения из базы данных и отображать в формате XML

Как видите, все очень просто и понятно. Вы можете использовать этот план в качестве руководства, если вам нужно написать бэкэнд на другом языке.

Планирование на стороне клиента

Внешний интерфейс должен вызывать серверную часть с помощью Ajax, аналогично подходу, который мы использовали в первом примере. Он должен обрабатывать отправку формы сообщения и обновлять окно чата новыми сообщениями через регулярные промежутки времени. Однако мы собираемся добавить еще одну функцию — мы будем использовать текущую метку времени UNIX, чтобы определить, какие сообщения уже были загружены, и только получать новые сообщения, уменьшая использование полосы пропускания и нагрузку на сервер. Вот примерный план внешнего кода:

  • на странице загрузки
  • установите текущую метку времени на 0 (все сообщения будут опубликованы после этого, т.е. все сообщения будут получены)
  • функция вызова для получения новых сообщений
  • функция: получать новые сообщения
  • отправить запрос на сервер, используя POST
  • вызов функции для анализа XML-ответа
  • добавьте таймер для вызова этой функции через секунду (увеличьте частоту, если нагрузка на сервер слишком высока)
  • функция: разбирать XML новых сообщений
  • установить текущую метку времени, как указано в XML
  • если возвращен код состояния ‘2’, новых сообщений нет, поэтому завершите вызов функции
  • иначе, для каждого сообщения в ответе, добавьте это к вершине окна сообщения в этом формате:
  • автор: сообщение
  • на бланке представить:
  • отправить запрос на сервер, используя POST, указав:
  • имя автора (указывается пользователем)
  • текст сообщения (указывается пользователем)
  • действие, отмечающее, что это почтовый запрос
  • отметка времени последнего запроса к серверу
  • пустое содержимое поля ввода сообщения, чтобы пользователь мог начать печатать другое сообщение
  • вызов функции для анализа XML-ответа (чтобы опубликованное сообщение было видно сразу)

Этот план может показаться гораздо более сложным, чем бэкэнд, но благодаря jQuery, код довольно короткий.

Планирование базы данных

Мы будем использовать базу данных MySQL для хранения сообщений (хотя любая база данных SQL будет работать, с некоторыми изменениями в коде). Нам нужна таблица с четырьмя столбцами: столбец для идентификатора каждого сообщения, два текстовых столбца для хранения автора сообщения и самого сообщения, а также столбец числовой метки времени для наших меток времени UNIX. Вот запрос, который создает таблицу:

CREATE TABLE `messages` (  `id` int(7) NOT NULL auto_increment,  `user` varchar(255) NOT NULL,  `msg` text NOT NULL,  `time` int(9) NOT NULL,  PRIMARY KEY  (`id`) ); 

Поскольку мы не можем сказать, какой длины будет сообщение, пока мы будем использовать текстовое поле.

Серверный код (XML)

Создавая бэкэнд, давайте сначала решим, какой бэкэнд должен выводить (чтобы определить интерфейс между бэкэндом и фронтэндом), и оттуда будем работать в обратном направлении. Вот простая структура XML:

 <?xml version="1.0"?> <response>  <status>1</status>  <time>1170323512</time>  <message>    <author>John Citizen</author>    <text>Hello world!</text>  </message>  <message>    <author>John Citizen</author>    <text>Hello world again!</text>  </message> </response> 

Обратите внимание, что я добавил тег 'status' со значением '1' . Как я упоминал выше, код состояния 1 будет представлять успешный запрос с новыми сообщениями, 2 как успешный без новых сообщений. Каждый экземпляр тега сообщения включает автора и его или ее сообщение.

Серверный код (PHP)

Теперь к задней части. Мне придется сделать это на PHP, но поскольку вывод — это XML, вы можете написать бэкэнд на любом языке — Perl, ASP, что вам нравится. Давайте начнем логически, определив некоторые значения конфигурации, чтобы мы могли легко изменить их позже. Нам нужны детали подключения к базе данных, количество сообщений, которые мы хотим сохранить в базе данных (базы данных могут обрабатывать тысячи строк, поэтому этот показатель может быть достаточно высоким), а также количество сообщений, отображаемых при входе пользователя в чат. Вот код:

 $dbhost = "localhost"; $dbuser = "root"; $dbpass = ""; $dbname = "chat"; $store_num = 10; $display_num = 10; 

Теперь нам нужно разобраться с основами самого бэкенда. Требуется подключение к базе данных, но мы также должны убедиться, что Internet Explorer не кэширует запрос и что выходные данные обрабатываются как XML. Чтобы удостовериться, что мы можем идентифицировать любые ошибки в коде, мы установим в отчете об ошибках «все ошибки». И чтобы легко работать с данными запроса, мы установим переменную для каждого параметра в запросе; каждая переменная будет принимать в качестве значения значение параметра запроса. Эти несколько строк делают свое дело:

 error_reporting(E_ALL); header("Content-type: text/xml"); header("Cache-Control: no-cache"); $dbconn = mysql_connect($dbhost,$dbuser,$dbpass); mysql_select_db($dbname,$dbconn); foreach($_POST as $key => $value)  $$key = mysql_real_escape_string($value, $dbconn); 

Строка foreach просматривает все данные POST, создает переменную для каждого параметра и присваивает ему соответствующее значение (например, path/to/file.php?variable=value устанавливает $variable в "value" ). Это упрощает процесс сбора данных запроса, поскольку нам не нужно указывать их вручную.

Далее мы перейдем к основному функционалу. Именно в этот момент мы обрабатываем вставку сообщений в базу данных и извлечение последних нескольких сообщений на основе количества отображаемых сообщений, как определено в $display_num . Я упомянул, когда мы планировали интерфейс, что мы будем указывать действие, сообщающее, что сообщение отправляется. Теперь нам нужно проверить это действие — давайте 'postmsg' параметру 'action' значение 'postmsg' чтобы указать, что мы выполняем эту проверку, и 'postmsg' данные в виде новой строки в базу данных; мы вставим текущую метку времени UNIX в базу данных, пока мы на ней.

Однако нам также необходимо очистить базу данных. В зависимости от ограничений места в вашей базе данных, вы можете ограничить количество сохраняемых сообщений. Как правило, регистрация сообщений не одобряется, поэтому я решил сохранить десять сообщений по умолчанию. Мы будем использовать функцию для получения идентификатора последней вставленной строки и определения удаляемых строк на основе значения этого id . Например, если мы вставим одиннадцатое сообщение, мы вычтем количество сохраненных сообщений (10) из id самого последнего (11), который дает нам порог id (в данном случае 1). Затем мы можем удалить все сообщения с id равным или меньшим этого порогового значения, что в этом примере приведет к удалению первого сообщения. И, благодаря SQL, мы можем сделать все это одним запросом.

Вот фрагмент 'postmsg' который проверяет действие 'postmsg' , вставляет сообщение в базу данных и очищает его на лету:

 if(@$action == "postmsg") {  mysql_query("INSERT INTO messages (`user`,`msg`,`time`)        VALUES ('$name','$message',".time().")");  mysql_query("DELETE FROM messages WHERE id <= ".        (mysql_insert_id($dbconn)-$store_num),$dbconn); } 

Разработчики, использующие другие технологии на стороне сервера, должны достаточно легко писать эквивалентный код. Обратите внимание, что мы вызываем функцию time, чтобы получить текущую метку времени UNIX. Мы можем с уверенностью предположить, что значение, которое возвращает время, вероятно, не изменится во время выполнения сценария (даже на медленном сервере этот сценарий выполняется менее чем за одну сотую секунды). Поэтому, когда мы возвращаем временную метку во внешний интерфейс позже, мы можем просто снова вызвать функцию времени, и значение все равно должно быть надежным.

Оставшийся код обрабатывает работу по извлечению последних сообщений из базы данных и выводу их в виде XML. Именно здесь вступает в игру XML, который я изложил выше. Однако основная часть кода находится в запросе MySQL. Мы используем возможности SQL для обработки большинства задач обработки, поэтому время выполнения сценария не изменяется. Вот требования для нашего SQL-запроса:

  • Он должен получать только автора и текст каждого сообщения.
  • Он должен получать только те сообщения, которые не были загружены ранее — у клиента есть метка времени последнего запроса, поэтому эта метка времени может быть вставлена ​​в запрос SQL.
  • Следует упорядочить сообщения так, чтобы последние поступали последними, позволяя выводить их в обратном порядке.
  • Он должен ограничивать количество сообщений, извлекаемых количеством, определенным в конфигурации.

Любой, кто знаком с SQL, согласится, что все это довольно просто. Для остальных из нас вот код, который делает свое дело. Сначала запрос:

 $messages = mysql_query("SELECT user,msg             FROM messages             WHERE time>$time             ORDER BY id ASC             LIMIT $display_num",$dbconn); 

Остальная часть кода является элементарной. Если результаты не возвращаются, установите код состояния на 0; в противном случае установите его на 1. Выведите исходный XML, XML для каждого сообщения и окончательный XML. Это все! Вот код:

 if(mysql_num_rows($messages) == 0) $status_code = 2; else $status_code = 1;   echo "<?xml version="1.0"?>n"; echo "<response>n"; echo "t<status>$status_code</status>n"; echo "t<time>".time()."</time>n"; while($message = mysql_fetch_array($messages)) {  echo "t<message>n";  echo "tt<author>$message[user]</author>n";  echo "tt<text>$message[msg]</text>n";  echo "t</message>n"; } echo "</response>"; 

Окончательный код находится во вложенном zip-файле, поэтому не беспокойтесь о копировании этого в ваш текстовый редактор. Теперь, когда серверная часть закончена, мы можем перейти к веселой работе — HTML и jQuery!

Код на стороне клиента (HTML)

Прежде чем мы перейдем к jQuery, нам нужно создать прототип HTML страницы. Таким образом, когда нам нужно определить, какие элементы мы выбираем для выборки или обновления, используя jQuery, мы знаем, что делать. Нам не нужно много: div-обертка, абзац для сообщений, форма с полями для имени пользователя и сообщения, а также кнопка «Отправить». Коротко отображаемое сообщение о загрузке добавит последний штрих — мы можем удалить его в соответствующее время, используя jQuery. Вот HTML-код:

 <div id="wrapper"> <p id="messagewindow"><span id="loading">Loading...</span></p> <form id="chatform"> Name: <input type="text" id="author" /> Message: <input type="text" id="msg" /> <input type="submit" value="ok" /><br /> </form> </div> 
Перейти на страницу: 1 | 2 | 3