Система длинных опросов-сообщений


Я собираюсь сделать несколько длинных опросов с помощью 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

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

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

4 12

4 ответа:

Да, способ, которым вы описываете это, - это то, как метод длительного опроса работает в целом. Ваш пример кода немного расплывчат, поэтому я хотел бы добавить, что вы должны делать 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);
          }     
       });
}

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

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

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

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

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

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

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

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