Я пытаюсь создать теоретическое приложение для веб-чата с php и jquery , я читал о длительном опросе и потоке HTTP, и мне удалось применить большинство принципов, представленных в статьях. Однако есть две основные вещи, которые я до сих пор не могу опустить.
success
jQuery для вызовов ajax, но как проверить данные, пока соединение все еще продолжается? Я буду благодарен за любые ответы, спасибо заранее.
Да, кометоподобные методы обычно взорвали мозг в начале – просто заставляя вас думать по-другому. И еще одна проблема заключается в том, что для PHP не так много ресурсов, потому что каждый делает свою комету в node.js, Python, Java и т. Д.
Я постараюсь ответить на ваши вопросы, надеюсь, что это пролило бы свет на эту тему для людей.
Как сервер узнает, когда было отправлено обновление? нужно ли постоянно запрашивать данные базы данных или есть лучший способ?
Ответ: в самом общем случае вы должны использовать очередь сообщений (MQ). RabbitMQ или функциональность Pub / Sub, встроенная в магазин Redis, могут быть хорошим выбором, хотя на рынке доступно множество конкурирующих решений, таких как ZeroMQ, Beanstalkd и т. Д.
Поэтому вместо непрерывного запроса вашей базы данных вы можете просто подписаться на MQ-событие и просто повесить, пока кто-то еще не опубликует сообщение, на которое вы подписаны, и MQ разбудит вас и отправит сообщение. Приложение для чата – очень полезный случай, чтобы понять эту функциональность.
Также я должен упомянуть, что если вы будете искать реализации Comet-chat на других языках, вы можете заметить простые, не использующие MQ. Итак, как они обмениваются информацией? Дело в том, что такие решения обычно реализуются как автономные однопоточные асинхронные серверы, поэтому они могут хранить все подключения в локальном массиве потоков (или что-то подобное), обрабатывать множество соединений в одном цикле и просто выбирать один и сообщать, когда это необходимо. Такие асинхронные серверные реализации – это современный подход, который отлично подходит для кометной техники. Однако вы, скорее всего, реализуете свою комету поверх mod_php или FastCGI, в этом случае этот простой подход не является для вас вариантом, и вы должны использовать MQ.
Это может быть очень полезно для понимания того, как реализовать автономный асинхронный Comet-сервер для обработки многих соединений в одном потоке. Последние версии PHP поддерживают Libevent и Socket Streams, поэтому можно также реализовать такой сервер на PHP. В документации PHP также есть пример .
Как проверить результаты во время соединения Ajax, все еще активен? Я знаю о функции успеха jQuery для вызовов ajax, но как проверить данные, пока соединение все еще продолжается?
Если вы проводите свои длительные опросы с помощью обычной техники Ajax, такой как простой XHR, jQuery Ajax и т. Д., У вас нет простого способа передачи нескольких ответов в одном запросе Ajax. Как вы уже упоминали, у вас есть только «успешный» обработчик, чтобы справиться с ответом в целом, а не с его ролью. В качестве обходного пути люди отправляют только один ответ на запрос и обрабатывают его в «успешном» обработчике, после чего они просто открывают новый запрос с длинным опросом. Именно так работает HTTP-протокол.
Также следует упомянуть, что на самом деле есть обходное решение для реализации потоковой функции с использованием различных методов, использующих такие методы, как бесконечно длинная страница в скрытом IFRAME
или использование многочастных HTTP-ответов. Оба эти метода являются определенными недостатками (первый из них считается ненадежным и иногда может приводить к нежелательным поведениям браузера, таким как индикатор бесконечной загрузки, а второй – к согласованной и простой кросс-браузерной поддержке, однако некоторые приложения, как известно, успешно используют механизм возвращается к длительному опросу, когда браузер не может правильно обрабатывать многочастные ответы).
Если вы хотите обрабатывать несколько ответов на один запрос / соединение надежным способом, вам следует рассмотреть возможность использования более совершенной технологии, такой как WebSocket, которая поддерживается самыми современными браузерами или на любой платформе, поддерживающей сырые сокеты (такие как Flash или если вы разрабатываете для мобильного приложения, например).
Не могли бы вы подробнее рассказать о очередях сообщений?
Очередь сообщений – это термин, который описывает автономную (или встроенную) реализацию шаблона Observer (также известную как «Публикация / Подписка» или просто PubSub). Если вы разрабатываете большое приложение, то одно из них очень полезно – оно позволяет разделить различные части вашей системы, реализовать асинхронный дизайн, управляемый событиями, и сделать вашу жизнь намного проще, особенно в гетерогенных системах. Он имеет множество приложений для реальных систем, я упомянул только пару из них:
Я надеюсь, что моя иллюстрация легко понять, однако очереди сообщений – очень широкая тема, поэтому обратитесь к упомянутым выше ресурсам для дальнейшего чтения.
Как проверить результаты во время соединения Ajax, все еще активен? Я знаю о функции успеха jQuery для вызовов ajax, но как проверить данные, пока соединение все еще продолжается?
Собственно, ты можешь. Я представил пересмотренный ответ для вышеупомянутого, но я не знаю, будет ли он еще ожидаться или был проигнорирован. Предоставление обновления здесь, чтобы получить правильную информацию.
Если вы поддерживаете соединение между клиентом и сервером, можно нажать на обновления, которые добавляются к ответу. Поскольку каждое обновление приходит в событие XMLHttpRequest.onreadystatechange
и значение XMLHttpRequest.readyState
будет равно 3. Это означает, что XMLHttpRequest.responseText продолжает расти.
Вы можете увидеть пример этого здесь: http://www.leggetter.co.uk/stackoverflow/7213549/
Чтобы увидеть JS-код, просто просмотрите источник. Код PHP:
<?php $updates = $_GET['updates']; if(!$updates) { $updates = 100; } header('Content-type: text/plain'); echo str_pad('PADDING', 2048, '|PADDING'); // initial buffer required $sleep_time = 1; $count = 0; $update_suffix = 'Just keep streaming, streaming, streaming. Just keep streaming.'; while($count < 100) { $message = $count . ' >> ' . $update_suffix; echo($message); flush(); $count = $count + 1; sleep($sleep_time); } ?>
В браузерах, основанных на Gecko, таких как Firefox, можно полностью заменить responseText
, используя multipart/x-mixed-replace
. Я не привел пример этого.
Не похоже, что с помощью jQuery.ajax
можно достичь такой же функциональности. Обратный вызов success
не срабатывает при каждом onreadystatechange
события onreadystatechange
. Это удивительно, поскольку в документации указано:
Однако механизм onreadystatechange не предусмотрен, так как успех, ошибка, полный и statusCode охватывают все мыслимые требования.
Таким образом, документация потенциально неверна, если я неправильно ее интерпретирую?
Вы можете увидеть пример, который пытается использовать jQuery здесь: http://www.leggetter.co.uk/stackoverflow/7213549/jquery.html
Если вы посмотрите на вкладку сети в инструментах Firebug или Chrome Developer, вы увидите, что размер файла stream.php
растет, но обратный вызов success
прежнему не является огнем.