Intereting Posts
Защита времени игры в javascript Разница между CMS (joomla, drupal) и Frameworks (Zend, Symfony, CI) WordPress не обрабатывает внешний php-файл PHP-массив, хранящийся в сеансе, имеет значение null, если мы инициализируем массив с тем же самым ключом, это проблема с кодировкой или проблема с php? асинхронная обработка с PHP – один рабочий на работу Экспорт контактов Gmail в CSV с помощью PHP MySql создает или обновляет строку с помощью ip? Crypt отличается от сервера, чем на локальной машине Будет ли включать ненужные php-файлы в замедление веб-сайта? Обновление скрытого поля с использованием автозаполнения в Yii2 Возьмите значение массива, если имеется определенный ключ с PHP Как очистить URI заголовков с помощью PHP? Что представляет собой символ серьезного акцента (`) (а не одинарная кавычка) в PHP? Регулярное выражение для запятой вне двойной цитаты в php Доступ к глобальной переменной изнутри класса

Общие вопросы по полному опросу / HTTP-потоку

Я пытаюсь создать теоретическое приложение для веб-чата с php и jquery , я читал о длительном опросе и потоке HTTP, и мне удалось применить большинство принципов, представленных в статьях. Однако есть две основные вещи, которые я до сих пор не могу опустить.

С длинным опросом

  • Как сервер узнает, когда было отправлено обновление? нужно ли постоянно запрашивать данные базы данных или есть лучший способ?

С потоковой передачей HTTP

  • Как проверить результаты во время соединения Ajax, все еще активен? Я знаю о функции 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). Если вы разрабатываете большое приложение, то одно из них очень полезно – оно позволяет разделить различные части вашей системы, реализовать асинхронный дизайн, управляемый событиями, и сделать вашу жизнь намного проще, особенно в гетерогенных системах. Он имеет множество приложений для реальных систем, я упомянул только пару из них:

  • Целевые очереди. Допустим, мы пишем наш собственный YouTube и вам нужно преобразовать видеофайлы пользователей в фоновом режиме. Очевидно, что у нас должен быть webapp с пользовательским интерфейсом для загрузки фильма и некоторого фиксированного количества рабочих процессов для конвертирования видеофайлов (возможно, нам даже понадобится несколько выделенных серверов, на которых наши рабочие только уйдут). Также нам, вероятно, придется писать наших сотрудников на C, чтобы обеспечить лучшую производительность. Все, что нам нужно сделать, это просто настроить сервер очереди сообщений для сбора и доставки задач преобразования видео из webapp в наших сотрудников. Когда рабочий появляется, он подключается к MQ и переходит в режим ожидания, ожидая новых задач. Когда кто-то загружает видеофайл, webapp подключается к MQ и публикует сообщение с новым заданием. Мощные MQ, такие как RabbitMQ, могут одинаково распределять задачи среди числа подключенных работников, отслеживать, какие задачи были выполнены, гарантировать, что ничто не потеряется, и предоставит интерфейс для отказа и даже пользовательский интерфейс администратора, чтобы просматривать текущие задачи в ожидании и статистику.
  • Асинхронное поведение. Наш комета-чат – хороший пример. Очевидно, мы не хотим периодически опроса нашей базы данных (что тогда используется комету?) – Не большая разница в выполнении периодических Ajax-запросов). Нам нужно, чтобы кто-то уведомил нас, когда появится новое сообщение чата. И очередь сообщений – это кто-то. Допустим, мы используем Redis key / value store – это действительно отличный инструмент, который обеспечивает реализацию PubSub среди своих функций хранения данных. Самый простой сценарий может выглядеть следующим образом:
    1. После того, как кто-то входит в чат, производится новый запрос Ajax long poll.
    2. Обработчик запросов на стороне сервера выдает команду Redis для подписки на канал «newmessage».
    3. Когда кто-то вводит сообщение в свой чат, обработчик на стороне сервера публикует сообщение в теме Redis «newmessage».
    4. Когда сообщение опубликовано, Redis будет немедленно уведомлять обо всех этих ожидающих обработчиках, которые подписались на этот канал раньше.
    5. После уведомления PHP-кода, который сохраняет запрос на длинный опрос, он может вернуть запрос с новым сообщением чата, поэтому все пользователи будут уведомлены. В этот момент они могут читать новые сообщения из базы данных, или сообщения могут передаваться непосредственно внутри полезной нагрузки сообщения.

Я надеюсь, что моя иллюстрация легко понять, однако очереди сообщений – очень широкая тема, поэтому обратитесь к упомянутым выше ресурсам для дальнейшего чтения.

Как проверить результаты во время соединения 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 прежнему не является огнем.