Введение

Модель веб-приложения Comet – это модель веб-приложения, в которой длительное HTTPS-соединение позволяет веб-серверу отправлять данные в браузер, без явного запроса со стороны браузера. Comet – это обобщающий термин, включающий в себя множество техник для реализации такого взаимодействия. Все эти методы используют возможности, изначально предусмотренные в браузерах, такие как JavaScript, а не сторонние плагины. Подход Comet отличается от традиционной модели работы веб, в которой браузер запрашивает целую веб-страницу за один раз. Среди других – Reverse Ajax, двусторонний веб и HTTP-push. Термин "Comet" не является акронимом, он был придуман Алексом Расселом в его блоге в 2006 году. В последние годы стандартизация и широкая поддержка WebSocket и Server-Sent Events сделали модель Comet устаревшей.

Ранние апплеты Java

Возможность встраивания Java-апплетов в браузеры (начиная с Netscape Navigator 2.0 в марте 1996 года) обеспечила устойчивую двустороннюю связь, используя TCP-сокет для обмена данными между браузером и сервером. Этот сокет может оставаться открытым, пока браузер отображает документ, содержащий апплет. Уведомления о событиях могут передаваться в любом формате – текстовом или бинарном – и декодироваться апплетом.

Первая система связи браузер-браузер

Первым приложением, использующим коммуникации между браузерами, был Tango Interactive, реализованный в 1996–1998 годах в Северо-Восточном центре параллельных архитектур (NPAC) при Сиракузском университете за счет финансирования DARPA. Архитектура TANGO запатентована Сиракузским университетом. Фреймворк TANGO широко использовался в качестве средства дистанционного обучения. CollabWorx коммерциализировал этот фреймворк, и он применялся примерно в десятке приложений для управления, контроля и обучения в Министерстве обороны США.

Первые приложения Comet

Первый набор реализаций Comet датируется 2000 годом, с проектами Pushlets, Lightstreamer и KnowNow. Pushlets, фреймворк, созданный Just van den Broecke, был одной из первых реализаций с открытым исходным кодом. Pushlets были основаны на серверных Java-сервлетах и клиентской библиотеке JavaScript. Bang Networks, стартап из Кремниевой долины, поддерживаемый соучредителем Netscape Марком Андреессеном, предпринял щедро финансируемую попытку создать стандарт для обмена данными в реальном времени для всего веб. В апреле 2001 года Чип Морнингстар начал разработку веб-сервера на основе Java (J2SE), который использовал два HTTP-сокета для поддержания двух открытых каналов связи между разработанным им HTTP-сервером и клиентом, разработанным Дугласом Крокфордом; функционирующая демонстрационная система существовала с июня 2001 года. Сервер и клиент использовали формат обмена сообщениями, который основатели State Software, Inc. согласились назвать JSON по предложению Крокфорда. Вся система, клиентские библиотеки, формат обмена сообщениями, известный как JSON, и сервер стали State Application Framework, части которого были проданы и использованы Sun Microsystems, Amazon.com, EDS и Volkswagen. В марте 2006 года инженер-программист Алекс Расселл ввел термин "Comet" в своей личной записи в блоге. Новый термин был игрой слов, основанной на названии Ajax (Ajax и Comet оба были распространенными чистящими средствами в США). В 2006 году некоторые приложения сделали эти технологии доступными для более широкой аудитории: многопротокольное веб-приложение для чата Meebo позволило пользователям подключаться к платформам чата AOL, Yahoo и Microsoft через браузер; Google добавил веб-чат в Gmail; JotSpot, стартап, впоследствии приобретенный Google, разработал систему совместного редактирования документов в реальном времени на основе Comet. Были созданы новые варианты Comet, такие как Java-фреймворк ICEfaces JSF (хотя они предпочитают термин "Ajax Push").

Реализация

Приложения Comet стремятся устранить ограничения веб-модели, основанной на постраничной загрузке, и традиционного опроса, предлагая двустороннее устойчивое взаимодействие посредством постоянного или долговременного HTTP-соединения между сервером и клиентом. Поскольку браузеры и прокси-серверы не предназначены для обработки событий с сервера, было разработано несколько методов для достижения этой цели, каждый из которых имеет свои преимущества и недостатки. Основным препятствием является спецификация HTTP 1.1, которая рекомендует клиентам быть осторожными при открытии множественных соединений. Следовательно, поддержание одного открытого соединения для событий в реальном времени может негативно сказаться на удобстве использования браузера: браузер может быть заблокирован от отправки нового запроса, ожидая результатов предыдущего, например, загрузки серии изображений. Эту проблему можно решить, создав отдельное доменное имя для информации в реальном времени, которое будет являться псевдонимом для того же физического сервера. Эта стратегия представляет собой применение шардинга доменов. Конкретные методы реализации Comet можно разделить на две основные категории: потоковая передача и длительный опрос.

Скрытый iframe

Основной метод для динамического веб-приложения — использование скрытого HTML-элемента iframe (встроенного фрейма, который позволяет веб-сайту встраивать один HTML-документ внутри другого). Этот невидимый iframe отправляется в виде блочного потока данных, что неявно объявляет его бесконечно длинным (иногда называемым "вечным фреймом"). По мере возникновения событий iframe постепенно заполняется тегами `<script>`, содержащими JavaScript для выполнения в браузере. Поскольку браузеры инкрементно отображают HTML-страницы, каждый тег `<script>` выполняется по мере получения. Некоторые браузеры требуют определенного минимального размера документа перед началом разбора и выполнения, чего можно добиться, предварительно отправив 1–2 кБ заполняющих пробелов. Одним из преимуществ метода с использованием iframe является его совместимость со всеми распространенными браузерами. Два недостатка этой техники — отсутствие надежного механизма обработки ошибок и невозможность отслеживания состояния процесса вызова запроса. Например, если основная веб-страница обслуживается с одного SLD, а сервер Comet расположен на другом SLD (у которого не включен механизм обмена ресурсами между доменами), события Comet нельзя использовать для изменения HTML и DOM основной страницы с использованием этих транспортных средств. Эту проблему можно обойти, создав прокси-сервер перед одним или обоими источниками, чтобы они выглядели как исходящие из одного домена. Однако это часто нежелательно из-за сложности или снижения производительности. В отличие от iframe или объектов XMLHttpRequest, теги `<script>` могут указывать на любой URI, и JavaScript-код в ответе будет выполнен в текущем HTML-документе. Это создает потенциальный риск безопасности для обоих серверов, хотя риск для поставщика данных (в нашем случае, сервера Comet) можно избежать, используя JSONP. Транспорт Comet с длительным опросом можно создать, динамически создавая элементы `<script>` и устанавливая их атрибут `src` на адрес сервера Comet, который затем отправляет JavaScript (или JSONP) с каким-либо событием в качестве полезной нагрузки. Каждый раз, когда запрос скрипта завершается, браузер открывает новый запрос, как и в случае длительного опроса XHR. Этот метод имеет преимущество кроссбраузерности и позволяет реализовывать междоменные решения. Определяется новый JavaScript-интерфейс EventSource и новый MIME-тип text/event-stream. Все основные браузеры, кроме Microsoft Internet Explorer, поддерживают эту технологию. Рабочая версия спецификации HTML 5 WebSocket API определяет метод создания постоянного соединения с сервером и получения сообщений через функцию обратного вызова onmessage. Протокол Bayeux, разработанный Dojo Foundation. Он сохраняет специфичные для браузера транспортные механизмы и определяет протокол более высокого уровня для связи между браузером и сервером, чтобы обеспечить возможность повторного использования клиентского JavaScript-кода с несколькими серверами Comet и позволить одному и тому же серверу Comet взаимодействовать с несколькими клиентскими JavaScript-реализациями. Bayeux основан на модели "издатель-подписчик", поэтому серверы, поддерживающие Bayeux, имеют встроенную поддержку этой модели. Протокол BOSH, разработанный XMPP Standards Foundation. Он эмулирует двунаправленный поток между браузером и сервером, используя два синхронных HTTP-соединения. Объект JSONRequest, предложенный Дугласом Крокфордом, может служить альтернативой объекту XHR. Использование плагинов, таких как Java-апплеты или проприетарный Adobe Flash (использующий протокол RTMP для потоковой передачи данных в Flash-приложения). Они имеют преимущество идентичной работы во всех браузерах при установленном соответствующем плагине и не требуют использования HTTP-соединений, но требуют установки плагина. Google объявила о новом API Channels для Google App Engine, реализующем API, подобный Comet, с помощью клиентской JavaScript-библиотеки в браузере. Этот API устарел.