Я занимаюсь долгим опросом с помощью 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
Мне нравится эта идея, но мне интересно, что другие думают об этом. Это идеальный способ приблизиться к этому? Любая информация будет полезна!
Чтобы добавить, нет определенного количества применений, которые могут быть на сайте, поэтому я ищу эффективный способ сделать это.
Да, как вы это описываете, как работает метод 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); } }); }
Вместо добавления нового столбца в качестве last_checked
вы можете добавить как last_checked_time
. Чтобы вы могли получить данные из last_checked_time
в current_time
.
(ie) DATA BETWEEN `last_checked_time` AND `current_time`
Если у вас только один пользователь, все в порядке. Если вы этого не сделаете, вы столкнетесь с осложнениями. Сделав это, вы также будете запускать один из множества запросов SELECT.
Некоторое время я твердо убеждался, что PHP и длительный опрос просто не работают из-за того, что PHP не имеет каких-либо межсетевых событий, управляемых событиями. Это означает, что вам нужно будет проверять свою базу данных каждую секунду / 2s / 5s вместо того, чтобы полагаться на события.
Однако, если вы все еще хотите это сделать, я бы заставил вашу систему обмена сообщениями записывать файл [nameofuser] .txt в каталог всякий раз, когда у пользователя есть сообщение, и проверять существование сообщения с помощью этого триггера. Если файл существует и не пуст, отключите запрос, чтобы получить сообщение, обработать, отправить назад, а затем удалить текстовый файл. Это уменьшит ваши накладные расходы SQL, в то время как (если вы не будете осторожны) увеличение вашего IO диска.
Структурно, ассоциативная таблица, безусловно, лучшая. Создайте новую таблицу, посвященную проверке состояния, с тремя столбцами: user_id
message_id
read_at
. Использование должно быть очевидным. Любая комбинация не в ней непрочтена.
Вместо создания столбца с именем last_checked вы можете создать столбец с именем: checked. Если вы сохраняете все сообщения в базе данных, вы можете обновить это поле в базе данных. Пример: