Длительный опрос - система сообщений

Я занимаюсь долгим опросом с помощью jQuery и PHP для системы сообщений. Мне любопытно узнать лучший/самый эффективный способ добиться этого. Я основываю этот простой длинный опрос.

Если пользователь сидит на странице "Входящие", я хочу использовать любые новые сообщения. Одна из идей, которую я видел, добавляет столбец last_checked в таблицу сообщений. PHP скрипт будет выглядеть примерно так:

query to check for all null `last_checked` messages
if there are any...
while(...) {
    add data to array
    update `last_checked` column to current time
}
send data back

Мне нравится эта идея, но мне интересно, что другие думают об этом. Это идеальный способ приблизиться к этому? Любая информация будет полезна!

Чтобы добавить, нет определенного количества применений, которые могут быть на сайте, поэтому я ищу эффективный способ сделать это.

Ответ 1

Да, как вы описали его, как работает метод Long Polling. Ваш пример кода немного расплывчатый, поэтому я хотел бы добавить, что вы должны сделать sleep() в течение небольшого промежутка времени внутри цикла while и каждый раз сравнивать время last_checked (которое хранится на стороне сервера ) и время current (которое отправляется с клиентской стороны).

Что-то вроде этого:

$current = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$last_checked = getLastCheckedTime(); //returns the last time db accessed

while( $last_checked <= $current) {
    usleep(100000);
    $last_checked = getLastCheckedTime();
}

$response = array();
$response['latestData'] = getLatestData() //fetches all the data you want based on time
$response['timestamp'] = $last_checked;
echo json_encode($response);    

И на стороне клиента JS у вас будет следующее:

function longPolling(){
        $.ajax({
          type : 'Get',
          url  : 'data.php?timestamp=' + timestamp,
          async : true,
          cache : false,

          success : function(data) {
                var jsonData = eval('(' + data + ')');
                //do something with the data, eg display them
                timestamp  = jsonData['timestamp'];
                setTimeout('longPolling()', 1000);
          },
          error : function(XMLHttpRequest, textstatus, error) { 
                    alert(error);
                    setTimeout('longPolling()', 15000);
          }     
       });
}

Ответ 2

Вместо добавления нового столбца в качестве last_checked вы можете добавить как last_checked_time. Чтобы вы могли получить данные из last_checked_time в current_time.

(i.e) DATA BETWEEN  `last_checked_time` AND `current_time`

Ответ 3

Если у вас только один пользователь, это нормально. Если вы этого не сделаете, вы столкнетесь с осложнениями. Сделав это, вы также запустите один из множества запросов SELECT.

Я уже давно убежден, что PHP и длительный опрос просто не работают из-за того, что PHP не имеет каких-либо межсетевых событий, управляемых событиями. Это означает, что вам нужно будет проверять свою базу данных каждую секунду /2s/5s вместо того, чтобы полагаться на события.

Тем не менее, если вы все еще хотите это сделать, я бы заставил вашу систему обмена сообщениями записывать файл [nameofuser].txt в каталог всякий раз, когда у пользователя есть сообщение, и проверять существование сообщения с помощью этого триггера. Если файл существует и не пуст, отключите запрос, чтобы получить сообщение, обработать, отправить назад, а затем удалить текстовый файл. Это уменьшит ваши служебные данные SQL, в то время как (если вы не будете осторожны) увеличение вашего IO диска.

Структурно, ассоциативная таблица, безусловно, лучшая. Создайте новую таблицу, посвященную проверке состояния, с тремя столбцами: user_id message_id read_at. Использование должно быть очевидным. Любая комбинация, в которой нет, не читается.

Ответ 4

Вместо создания столбца с именем last_checked вы можете создать столбец с именем: checked. Если вы сохраняете все сообщения в базе данных, вы можете обновить это поле в базе данных. Пример:

  • Пользователь 1 отправляет пользователю 2 сообщение.
  • PHP получает сообщение с использованием системы длинного опроса и сохраняет сообщение в таблице.
  • Пользователь 2, когда он подключен к сети, отправит сигнал на сервер, уведомив сервер, что пользователь 1 готов к приему сообщений.
  • Сервер проверяет таблицу для всех сообщений, которые не "проверены" и возвращают их.