базовый курс

ГРУППА КУРСА

Частые опросы

Частые опросы устроены следующим образом: страница через определённые промежутки времени отправляет запросы на сервер, где выясняется, появились ли новые данные с мометна прошлого запроса. Если данные есть, то сервер их отправляет. По сути, частые опросы - лишь эмитация COMET, потому что не сервер принимает решение, когда отправлять ответ. Он отвечает сразу, как при обычном запросе. А к технологии COMET частые опрсы относят потому, что пользователь не видит процесса взаимодействия страницы с сервером и ничего для этого не делает. А когда на сервере появляются новые данные, то страница их получает.

Преимущество этого способа заключается в том, что он реализуется проще всего. Нужно всего лишь запустить цикл, в котором будут отправляться запросы. Но есть и недостаток - многоие запросы будут лишними, в них не будут передаваться данные и это ненужная нагрузка на сервер. Частые отпросы применимы тогда, когда нет необходимости обеспечивать моментальную отправку данных клиенту, как только они появились на сервере. Если можно отправлять запросы один раз в 10 секунд или один раз в минуту, и это не вредит функционалу сайта, то можно использовать данный способ, потому что такое количество запросов, даже бесполезных - это не слишком большая нагрузка на сервер. Хотя это достаточно условно, нужно учитывать и другие факторы, мощность сервера и число посетителей.

Для примера выведем комментарии из таблицы comments которая использовалась в этой теме. Если у Вас ещё нет такой таблицы, то создайте её. В ней достаточно двух полей: id и text. Другие использоваться не будут. Создадим страницу, на которую будут выводиться комментарии при добавлении в базу данных. Чтобы сервер отправлял только те комментарии, которых ещё не получала страница, нужно запоминать id последней полученной записи и каждый раз в запросе указывать серверу, с какой записи начинать отправку. Код страницы будет такой:

HTML код:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title>Страница</title>
<meta charset="utf-8">
</head>
<body>
<div></div>
</body>
</html>

Блок находится на странице для того, чтобы помещать в него комментарии. Добавим на страницу скрипт, отправляющий запросы на сервер.

JavaScript:

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var div=document.querySelector('div');
var id=0;
sendxhr = function ()
  {
  var xhr = new XMLHttpRequest();
  xhr.open('POST','newcomment.php');
  xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  xhr.send('id='+id);
  xhr.onreadystatechange=function ()
    {
    if (xhr.readyState==4 && xhr.status==200)
      {
      var an=xhr.responseText;
      if (an)
      take(an);
      }
    }
  }
function take(an)
  {
  var comments=an.split('(na)');
  id=comments.pop();
  for (var i=0; i<comments.length; i++)
    {
    div.innerHTML+=comments[i]+'<br>';
    }
  }
setInterval(sendxhr, 1000);

Комментарии:

10 - находим блок

11 - объявляем переменную id, в которую будем записывать id последней полученой записи. Объявляем её на глобальном уровне, чтобы значение не терялось.

12 - функция отправки запроса

14 - создаём объект XMLHttpRequest

15 - параметры запроса

16 - устанавливаем Content-Type

17 - отправляем запрос. В теле запроса отправляем id

18 - обработчик события Readystatechange

20 - если запрос завершён и он успешный,

22 - записываем ответ сервера в переменную an

23 - если ответ сервера не пустой,

24 - то вызываем функцию обработки результата и передаём ей ответ

28 - функция обработки результата

30 - разделяем строку ответа по разделителю "(na)" и записываем в массив comments. В результате каждый комментарий будет находиться в отдельном элементе массива. А в последнем элементе будет id последней записи. О том, как формируется такая строка, я расскажу при рассмотрении серверной части технологии.

31 - удаляем последний элемент из массива и записываем его значение в переменную id. При следующем запросе это значение будет отправлено на сервер, чтобы серверный скрипт отправлял записи, имеющие больший id, а значит добавленные позже.

32 - перебор массива comments

34 - каждый комментарий добавляется в блок на отдельной строке

37 - отправка запроса один раз в секунду

Скрипт работает так: на сервер отправляется запрос с id последней полученой записи. Если на сервере появились новые записи, то сервер отправит их, они будут записаны в переменную an и обработаны. А если на сервере новых записей нет, то ответ будет пустым. Тогда скрипт больше ничего не делает до следующей отправки запроса.

В качестве разделителя используется строка из 4 символов - "(an)". Это сделано для наглядности. На практике можно использовать более короткий разделитель, если Вы уверены, что такой набор символов не окажется в каком-то комментарии.

В нашем примере обращение к серверу происходит каждую секунду. Но на хостинге такое количество запросов, конечно, нежелательно.

Страница запускает на сервере файл newcomment.php. Вот код этого файла:

newcomment.php:

+
1
2
<?php
header('Content-type: text/html; charset=utf-8');
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$db=mysqli_connect('localhost', 'root', '', 'mybase');
$current_id=$_POST['id'];
if (!isset($current_id))
$current_id=0;
$query="SELECT MAX(id) FROM comments";
$result=mysqli_query($db, $query);
$max_id=mysqli_fetch_row($result);
if ($max_id[0]>$current_id)
  {
  $query="SELECT * FROM comments WHERE id > $current_id";
  $result=mysqli_query($db, $query);
  for ($i=0; $i<mysqli_num_rows($result); $i++)
    {
    $row=mysqli_fetch_assoc($result);
    $an.=$row['text'].'(na)';
    }
  $an.=$row['id'];
  echo $an;
  }
mysqli_close($db);

Комментарии:

3 - подключение к БД

4 - получаем от страницы id последнего комментария и записываем в переменную $current_id

5 - если от страницы не получен id,

6 - то присваиваем переменной 0

7, 8, 9 - узнаём максимальный id в таблице

10 - если максимальный id больше чем id, полученный от страницы, значит в таблице появились новые записи

12 - запрос на выборку записей с id большим чем $current_id

13 - запрос к БД

14 - обработка результатов выборки

16 - помещаем запись из результата в массив $row

17 - в переменную $an добавляем текст комментария из массива $row, а также строку "(na)". Эта строка будет отделять комментарии друг от друга. Переменная $an - это будет ответ сервера.

19 - в конец строки ответа добавляем id записи из массива $row. Так как это делается после завершения цикла, то $row содержит id последней записи в выборке.

20 - отправляем ответ сервера

22 - закрываем соединение с базой данных

Сервер должен получать id последнего комментария именно от страницы, а не запоминать каким-то способом. Это гарантирует, что данный комментарий страница точно получила.

Прежде чем запускать страницу, добавьте в таблицу comments хотя бы две записи. Это нужно потому, что я не делал проверку наличия записей в таблице. Ничего сложного здесь нет, но чтобы в примере не было лишнего кода, я эту возможность не добавлял.

Запустите страницу, отправляющую запросы на сервер. На странице должны сразу появяться все записи, которые есть в таблице. Откройте phpMyAdmin. Добавляйте в таблицу новые записи, они должны отображаться на странице.