Система длинных опросов-сообщений
Я собираюсь сделать несколько длинных опросов с помощью 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 ответа:
Да, способ, которым вы описываете это, - это то, как метод длительного опроса работает в целом. Ваш пример кода немного расплывчат, поэтому я хотел бы добавить, что вы должны делать
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 отправляет пользователю 2 сообщение.
- PHP получает сообщение с помощью системы long-polling и сохраняет его в таблице.
- пользователь 2, находясь в сети, посылает сигнал на сервер, уведомляя сервер о том, что пользователь 1 готов к приему сообщений
- сервер проверяет таблица для всех сообщений, которые не были "проверены" и возвращает их.