Пользователь
0,0
рейтинг
25 сентября 2010 в 21:48

Разработка → Comet — обзорная статья

Данная статья написана исходя из собственного опыта и является скорее поводом к обсуждению технологии, нежели к попытке полноценно осветить тему :)

Что такое COMET?


Comet неологизм, описывающий модель работы веб-приложения. В обычном цикле обработки запроса, клиент инициирует соединение и запрашивает интересующий его документ. После отдачи данных, связь разрывается. В случае с Сomet, сервер инициирует соединение и отправляет клиенту сообщение. Типичный пример Comet это оповещения в Facebook, Twitter, чат в Gmail и др.




Существующие подходы


Существует несколько основных подходов как достичь желаемого результата.

* Polling: Достатоно простой метод, основанный на переодическом опрашивании сервера;
* Long poll: Способ при котором клиент открывает соединение и не закрывает его до тех пор, пока не наступит событие. По наступлению события, клиент получает оповещение и снова открывает соединение;
* «бесконечный» iframe: Метод основан на особенностях загрузки html документов. Создается невидимый iframe, который читает «бесконечный» файл. При наступлении события, добавляется новая строка в файл. Строка может быть кодом javascript, который исполниться, при получении на клиенте;
* Flash сокеты: Простой метод, при загрузке страницы, создается сокет, который слушает сервер. При наступлении события, сервер посылает команду клиенту на слушающий сокет, на определенный порт;
* HTML5 WebSockets: Метод похож на метод с Flash сокетом, за исключением того, что сокет создается нативными средствами браузера.
* другие методы

У каждого из методов есть свои плюсы и минусы. Ниже приведена страница сравнения основанная на собственном опыте.
Метод Сложность реализации Поддерживаемые браузеры Требовательность к ресурсам
Polling Просто Все возможные браузеры В зависимости от настроек, может создавать достаточно большой трафик
Long poll Средне Все возможные браузеры На каждого клиента создается соединение, которое остается открытым, до тех пор, пока не произойдет событие или пользователь не уйдет со страницы
«бесконечный» iframe Много нюансов, в зависимости от браузера Практически все Соединение постоянно открыто
Flash сокеты Достаточно просто Все браузеры, с поддержкой Flash
HTML5 WebSocet Просто Chrome, +


Технологии


Реализовывать самостоятелньо один из методов — достаточно трудоемкий процесс, за исключением наверно обычного pollingа. Поэтому целесообразно использовать готовые решения. Часто они реализованы как самостоятельные push-сервера. Для взаимодействия с приложением, могут применяться различные интерфейсы, зависящие от конкретной реализации. Как пример это может быть js api, RESTfull запросы, протокол AMQP и другие.

Тут можно посмотреть таблицу наиболее популярных комерческих и свободных разработок:



Помимо этого стоит отдельно отметить такие разработки как APE, Hookbox, Juggernaut и Mochiweb.

Интеграция с ruby


Первое что выдает google, при наборе: «comet + ruby» это библиотека Juggernaut. На сайте есть отличная документация. Устанавливается все за 5 минут. В принципе достойное решение для внутренних проектов. Некоторые его используют также в production. Из недостатков следует отметить два момента: первый, необходимо иметь установленный flash на браузере и второй, существуют проблемы при работе из-за файрвола.

Следующий вариант APE (Ajax Push Engine). Довольно новая разработка. Состоит из трех основных частей: JavaScript framework, Push сервера и протокола. Проект бесплатный, выдерживает большие нагрузки и работет во всех браузерах. Для взаимодейтсвия с приложением, использует свой протокол, команды передаются в формате JSON. Интеграция с Rails приложением немного болезненна из-за несоответсвия путей но тем не менее, запустить можно достаточно быстро. Из минусов можно выделить то, что JavaScript framework достаточно много весит.

Один из самых удобных и надежных решений по моему мнению — hookbox. Написан теми же разработчиками что и orbited. Проект был существенно упрощен и исправлены многие баги. Состоит также из трех компонентов: push сервер, js библиотека и протокол. Интеграция с приложением реализована с помощью REST запросов. Два недостатка которые были обнаружены: проблема с мигающим курсором в Opera и некоторые проблемы с push сервером, при длительном простое.

Полезные ресурсы


Общая информация


Статья в википедии
HTTP streaming
Материалы с сайта javascript.ru
Comet maturity guide

Nginx & Comet
Nginx http push server

WebSockets

Реализации


Hookbox
Mochiweb
Juggernaut
Ajax Push Engine

Примеры реализации в ruby и RoR


Comet & Ruby & Redis
Comet demo for ruby on rails
Ruby & Orbited
Orbited & Ruby
APE & Rails

Comet & Orbited #1
Comet & Orbited #2
Comet & Orbited #3

php simple chat example
balepc @balepc
карма
20,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (78)

  • +19
    будущее за вебсокетами
    • 0
      Определенно, но судя по тому как «активно» внедряется стандарт html5, нам еще придеться поработать с тем что есть :)
      • 0
        Из 4-х популярных движков два (Gecko и WebKit) поддерживают, два (Trident и Presto) нет, причём первый из них в ближайшем будущем вряд ли введёт поддержку, за вторым не слежу. Имхо, с релизом Fx 4.0 можно смело вводить на продакшене на сайтах, ориентированных либо на «ИТ-продвинутую аудиторию», либо на СМБ (SaaS и т. п.). На сайтах для «гламурных девочек» и КБ рановато — ждём поддержки от Оперы и MS (то есть когда в мире не останется ИЕ <10 :) то есть в следущем веке, видимо :( ), либо используем поллинг, флэш и т. п.
        • +3
          Единообразия не будет в этом мире, поэтому костыли наше все
        • +1
          Слышал что веб-сокеты эмулируются маленькой флешкой. Т.е. ты используешь интерфейс веб-сокета а там уже если они поддерживаются — то юзаются они. иначе через флеш-эмулятор
          • –1
            Тоже что-то слышал, но примеров использования, насколько это всё прозрачно и для клиента, и для сервера не попадалось. Вообще как-то думал, что флэш вещь в себе и c JS взаимодействовать не может
            • +2
              Еще как может :-) И не одним способом, к тому же.
            • 0
              chat.websockets.ru/ вот пример из доклада на РИТ (сам доклад есть тут websockets.ru/node/6)
          • 0
            эмулируются маленькой флешкой
            Вот я пользуюсь плагином Flashblock, мне как быть тогда, я ж даже эту флэшку маленькую найти не смогу чтоб включить.
            • 0
              А вам и не надо её включать. Ваш браузер итак умеет ВебСокеты, которые она призвана эмулировать.
              • 0
                Ну а если это не я?
                • 0
                  Браузер не грамотный допустим.
                  • +2
                    а в не грамотном браузере не стоит FlashBlock — всё очень просто ;-)
          • 0
            Если бы маленькие флешки везде шли, то было бы прекрасно :(
            • 0
              они идут везде.
    • 0
      В том и дело, что будущее. А сейчас изворачиваться приходится.
      p.s. Отличная статья, спасибо.
    • –4
      Создание соединения достаточно трудоемкая задача, а еще и проворачивание этого через HTTP? ИМХО, надо смотреть в обычные IPv6 сокеты или думать над тем как снизить время установки соединения (прохождение через огромное количество маршрутизаторов и замена заголовков сводит на НЕТ прелести AJAX и ЖИВОГО Интернета).

      P.S. Возможно проблему и не удастся победить на WiFI и Bluetooth, но почему не попробовать разобраться с проводной связью?
      • +3
        прохождение через огромное количество маршрутизаторов и замена заголовков сводит на НЕТ прелести AJAX и ЖИВОГО Интернета

        Пардон, но Вы точно не бредите? И «обычные» IPv6 сокеты для кого сейчас обычные? И вообще, Вы о чем? -)
      • +2
        Соединение создаётся только раз, дальше пакеты гоняются от сервера к клиенту и обратно пока клиент или сервер не упадут :) И, честно говоря, пока не заметил что там такого сложного в создании соединения
      • +2
        Ммм, время прохождение пакета — миллисекунды. Соединение устанавливается 2 парами запросов, если память не изменяет. Задача может и трудоемкая ( особенно если убуриться в уровни, адресацию и прочее ) но успешно решена в современном мире. Может быть и не уложимся целиком в замечаемые 0.1 секунды но вполне укладываемся в критичные 0.5 сек.

        А вообще практика показывает что задержки сети не важны.
    • +1
      Дада, вебсокетами, canvasGL и так далее, а что ближайшие 3-4 года делать-то?
  • –6
    Блин, извините, конечно, но я перепугался — думал, на Хабре дело уже до бытовой химии дошло )))
  • 0
    Было бы интересно видеть библиотеку(и) с WebSockets, имеющую прозрачный костыль для старых браузеров и видимо без дополнительных серверов.
    • 0
      >и видимо без дополнительных серверов.

      Знаете какие-то сервера, которые уже поддерживают веб-сокеты?
      • 0
        Я имел в виду без push сервера. А веб сокет поддерживает «сервер» браузера, не так ли?
        • 0
          Как я понял концепцию веб-сокетов, поддержка со стороны сервера нужна по любому и для отправки сообщений клиенту, и для получения сообщений от него. Apache+mod_php это явно не потянут :)
    • +2
      Что касается библиотек, пожалуйста:
      github.com/gimite/web-socket-js
      github.com/LearnBoost/Socket.IO
      • +1
        использую socket.io последние месяца 4. На сайте висит постоянно человек 10-20. Полёт нормальный, легко интегрировалось.
  • +1
    А разработчики hookbox отшли от orbited? Или продолжают делать параллельно?
  • 0
    > В обычном цикле обработки запроса, клиент инициирует соединение и запрашивает интересующий его документ. После отдачи данных, связь разрывается.

    Насколько я понял из английской википедии Comet не преодолевает разрывы соединений(да и есть Keep Alive), а общее обозначение push технологий.
  • 0
    Я надеялся вы хоть что-нибудь напишете, а не просто набор ссылок, который гуглится за 5 минут.

    Про Long polling вы не правы. Не обязательно открывать каждый раз соединение для нового события. По одному соединению можно частями передавать любое количество действий, а открывать новое, когда браузер сбросит его таймауту. Таким образом, кстати, работает Orbited.
    • –2
      Фишка Long polling в том, чтобы веб-сервер не возвращал ответ клиенту сразу-же после получения от него него запроса, а ждал возникновения некоторого события (или таймаута). Когда событие возникает — клиенту отправляет ответ. Получив ответ, клиент закрывает соединение (так уж устроен веб).

      Как вы хотите по одному соединению передавать любое количетсво действий? :)
  • +2
    В случае с Сomet, сервер инициирует соединение и отправляет клиенту сообщение.
    Неправда. В Comet соединение инициирует клиент.
    Pooling
    Вы «pulling» имели ввиду?
    • +2
      таки Polling — термин, обозначающий периодический опрос чего с целью узнать об изменении состояния или получении новых данных.
      • +5
        Всё одно не «pooling».
    • +1
      Автор немного позабыл об основах HTTP
      • +2
        Минусует видимо тот кто их тоже позабыл. По протоколу сервер не может быть инициатором соединения. Или я не прав?
        • +1
          Да, вы правы
          Совсем по-простому в long polling клиент начинает качать «бесконечный» файл с сервера, где время от времени передаются куски данных
    • 0
      Хотя ХЗ :) Тут же длинные запросы — это скорее pulling :)
    • 0
      Туда же:
      Long poll: Способ при котором клиент открывает соединение и не закрывает его до тех пор, пока не наступит событие.
      Клиенты вроде не закрывают соединений (помимо прерывания пользователем и других редких случаев) и события, о которых речь, происходят на сервере.
    • 0
      Все верно. Ошибся «поллинг» (polling) — периодический опрос сервера стандартными пакетами. Спасибо
    • 0
      Неправда. В Comet соединение инициирует клиент.


      Технически да. Но для конечного пользователя это выглядит как сигнал с сервера.
      • +2
        Вы же на ресурсе для технических специалистов. Тут надо соблюдать точность.
      • 0
        Хм… Я как-то думал, что это полностью асинхронное двухстороннее взаимодействие и по сути нет клиента и сервера, есть полноценные партнеры, которые могут обмениваться сообщениями. То есть сообщение в приложение (например чат) может послать и клиент (пользователь набрал новое), и сервер (другой пользователь набрал или произошло какое-то системное событие)
  • +2
    ох уж этот брОузер
  • +3
    ох уж эта хабраграмматика… только здесь слово «нюанс» пишут с мягким знаком.
  • 0
    Как раз над этой проблемой думаю. Флеш очевидно не является приемлемым (ибо не являеся частью HTML и есть не под все платформы), среди остальных вариантов откровенно не могу определиться. Постоянный коннект — зло. У пулинга большие накладные расходы.

    Сокеты хороши ровно до тех пор, пока не встречается клиент с НАТом…
    • 0
      а что там за проблемы с натом?
      • 0
        каким образом будет обращение на сокет клиенту, находящемуся за натом? На какой порт какого адреса?
        • 0
          ну так клиент открывает соединение на тотже адрес сервера и тотже 80 порт и по нему уже всё ходит.
          или я чегото не понимаю в вебсокетах?
          • 0
            если «ходит», то это сублимация и подмена понятий. Нормальное взаимодействие должно идти в обратном виде, так, чтобы сервер мог отправлять клиенту сообщения.
            • 0
              в каких ситуациях «нормально», чтобы сервер открывал соединение до клиента?

              в клиент-серверной архитектуре нормально, когда запросы инициируются клиентами, в тот момент когда пользователю нужен сервис.
              • 0
                Если сервер отсылает уведомление клиенту, то это уже не клиент-серверная архитектура, как бы.
                • 0
                  в каком-то смысле да, не совсем.

                  хотя идея к-с архитектуры всёже не в структуре протокола типа запрос-ответ, а в ассиметрии распределения ресурсов и сервиса их предоставления.
                  сервисом может быть, например, маршрутизация/коммутация сообщений/каналов (IM, VoIP, брокеры corba/com всякие) — протокол уже не укладывается в запрос-ответ, но архитектура остаётся клиент-серверная.
                  • 0
                    Мне кажется, что это всё мухлёж. К-С однозначно говорит, что запросы выполняются только по запросу клиента, и никак иначе. Как только появляется «сервер решил сказать клиенту», это уже не К-С. Его упихивают кое-как, но это уже выход за рамки модели. Нужно думать другую модель.
                    • 0
                      я учился по другим учебникам, где клиент-серверность представлялась более абстрактно.

                      альтернативная модель уже есть — обмен сообщениями между участниками (уже упомянутые corba/com, d-bus, AMQP), но им всем нужен сервер обеспечивающий шину/брокер.

                      а несовместимый с natом «мухлёж» типа ftp давно научились обходить.
                      • 0
                        Я немного про другое. Если реальная ситуация перестаёт соответствовать модели, то лучше перестать мурыжить старую модель и начать думать о новой. Иначе мы будем вынуждены решать совершенно противоестветственные для модели задачи (например, формировать исходящую очередь на сервере, отрабатывать отказы в приёме и т.д.). Сами эти задачи нормальные, но их упихивание в существующие модели может привести к очередной плезиосинхронности (есть у связистов такая уродливая конструкция возникшая из совместимостей с старым хламом).

                        Куда лучше задуматься о формальном описании новой модели, которая бы штатно предусматривала соединения с клиентом через инициируемый клиентом канал.

                        Про ФТП лучше не вспоминать, это самое уродливое решение в современном ИТ (я про то, что маршрутизаторы лазят своими грязными руками в L5 и выше). Второй вариант ФТП (passive) куда логичнее.
                      • 0
                        есть еще broker-less схемы, самый яркий пример — ZeroMQ
            • 0
              а…
              так вы о том, что постоянные соединения вообще зло.
              ну так тогда и аськи с жабберами зло. вроде от этого никто особо не срадает, кроме сисадминов прописывающих правила на файрволе.
              • 0
                Хм… Интересный аргумент. Подумаю. Для начала нужно подумать, почему «зло»…

                В браузере они «зло», потому что вечно висит полоска загрузки и бесит.
                • 0
                  полоска загрузки — это интерфейсный элемент.
                  iftop/netstat вам тоже много полосок покажут даже на домашнем десктопе.
                  а в офисной сети с каким-нибудь AD/ldap так лучшеб держалось одно постоянное соединение к каталогу.
                  • 0
                    Интерфейсный, но очень важный. Пока она будет появляться при незакрытом коннекте, любые persistent connection в браузере будут раздражать конечного пользователя (который будет это воспринимать как признак тормозящего сайта).
                    • 0
                      хром 7.0.xxx никаких полосок на websockets не рисует.
                      • 0
                        Ага. Вот это уже серьёзный аргумент. Если остальные браузеры себя так же вести будут, это определит выбор технологии.

                        Я подумал, кроме полоски и необходимости серверу держать большое количество коннектов, других проблем я не вижу.

                        Вторая часть решаема, первая, видимо, тоже.
                        • 0
                          Никаки если. ВебСокеты и были созданы для решения множества проблем с текущими реализациями, включая интерфейсные.
                        • +1
                          полоса загрузки висит при работе через Iframe. При эмуляции сокетов через AJAX, или Flash или работе с WebSockets ее нет.

                          На стороне сервера решается с помощью асинхронности. (Простейший пример dklab.ru/lib/dklab_realplexor/)
    • 0
      Пока будет НАТ и отсутствие поддержки UDP (для реализации STUN) в браузерах, не будет ничего иного, кроме открытия и удержания соединения клиент-сервер (кроме конечно периодических ping/push но они не рассматриваются из-за заметной неэффективности при даже небольшом увеличении количества клиентов).
  • 0
    Не сервер инициирует соединение, а клиент!
  • +3
    Еще comet сервер Realplexor для PHP от Дмитрия Котерова.
    • 0
      парсер съел ссылку
      habrahabr.ru/blogs/hi/79189/
    • 0
      Там API клиента пока на ПХП только. А сам сервер не привязан к языку программирования.
  • +1
    Не так давно понадобился comet в работе, заюзал Lift, не жалуюсь.
    На их сайте пишут: Lift's Comet support is unparalled
    Простейший комет чат — полэкрана кода: liftweb.net/getting_started
    Ну и вся сила Java и JVM за спиной на случай чего-то более сурового.
  • +2
    В J2EE Comet появился только в спецификации Servlet 3.0. До этого каждый вендор предлагал (и до сих пор предлагает) свой способ реализации. Однако, есть фреймворк под названием Atmosphere, который унифицирует реализацию comet-a единым API. Оч. рекомендую.
  • +1
    Спасибо вам за то, что открыли для меня Hookbox. После APE он кажется элементарным. Хотя APE тоже крайне достойный проект.
  • +1
    www.caucho.com/resin/index.xtp — resin web-server, один из первых comet-серверов
  • 0
    и еще dklab_realplexor тоже ничего

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.