Comet — любая модель работы веб-приложения, при которой постоянное HTTP-соединение позволяет веб-серверу отправлять (push) данные браузеру без дополнительного запроса со стороны браузера.

На схеме изображено место комет сервера в процессе работы.

На схеме изображено место комет сервера в процессе работы.


Взаимодействие с комет сервером построено следующим образом.
  1. Браузер открывает страницу сайта
  2. После загрузки страницы JavaScript устанавливает постоянное соединение с comet сервером.
  3. Пока открыта страница ваш сервер может отправить произвольное сообщение клиенту. Для этого он обращается с помощью Api к комет серверу и передаёт ему сообщение.
  4. Комет сервер используя открытое соединение с браузером доставляет полученное сообщение в браузер.
  5. JavaScript Api полученное от сервера сообщение предаёт в ваш callback


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


Существует не мало подходов для реализации, но актуальным на данный момент является WebSockets, в использовании остальных подходов таких как Polling, Long polling, «бесконечный» iframe и Flash сокеты уже почти необходимости так как вебсокеты уже поддерживаются всем современными браузерами.

Реализации комет серверов


Будет хорошо если кто-то ещё поделится ссылками на похожие проекты.
Название Лицензия API
Centrifuge MIT Python, Ruby, Java, PHP
dklab_realplexor GPL PHP
Nginx Push Stream Module GPL REST API
APE Project GPL REST API
comet-server.ru Как сервис,
С установкой на свои сервера
Delphi, C, C++, Эйфель, Java, Лисп, Perl,
PHP, Python, Ruby, Smalltalk, Node.js,
Bash, Компонентный Паскаль и Tcl
(Все языки для которых есть MySQL клиент)
fanout.io Как сервис,
С установкой на свои сервера
Python, Ruby, PHP, Node, Go, Django
pusher.com Как сервис REST API и библиотеки для Ruby, PHP, .NET,
Node.js, Python
hydna.com Как сервис C++, Erlang, Go (Push only), Java, JavaScript,
Julia (Push only), Lua (Push only), .NET, Node.js,
Objective-C, PHP (Push only), Python (Push only),
Ruby (Push only)
tambur.io Как сервис Ruby, Python, PHP, Java, Erlang
Есть ещё сводная таблица реализаций комет серверов, но она датирована аж 2009 годом

Построение простого чата на php


Разберём пример построения чата. В качестве комет сервера будем использовать comet-server.ru

Чат будет работать следующим образом:
  • Пользователь заходит на страницу и сразу подписывается с помощью JavaScript Api на канал для получения сообщений чата.
  • Для того что бы отправить сообщение пользователь отправляет текст сообщения через ajax на php сервер.
  • PHP сервер полученное сообщение обрабатывает, по желанию сохраняет к себе в БД и делает с ним что угодно.
  • Затем php сервер соединяется с комет сервером и передаёт ему CometQL запрос на отправку сообщения в канал.
  • Комет сервер полученное от php сервера сообщение рассылает всем кто подписан на канал.

Код для получения сообщений из чата
<!DOCTYPE HTML>
<html>
<head>
    <!-- Подключаем библиотеки -->
    <script src="//comet-server.ru/CometServerApi.js" type="text/javascript"></script>
    <script src="//comet-server.ru/doc/CometQL/simplePhpChat/jquery.min.js" type="text/javascript"></script>
</head>
<body>

<!-- Блок в который мы добавим полученное сообщение -->
<div id="textHolder" style="margin-top:10px; border:1px solid #000;padding:10px;"></div>
<hr>
<input type="text" id="msgText" placeholder="Текст сообщения"><input type="button" value="Отправить"  onclick="sendMsg();">

Для связи с комет сервером используется <a href="http://comet-server.ru/wiki/doku.php/comet:cometql">CometQL</a>. CometQL - это api для работы с комет сервером по протоколу MySQL.
<script type="text/javascript">
$(document).ready(function(){

    /** 
     * Подписываемся на получение сообщения из канала SimplePhpChat
     */
    CometServer().subscription("SimplePhpChat", function(event){
        console.log("Мы получили сообщение из канала SimplePhpChat",  event.data, event);
        $("#textHolder").html( $("#textHolder").html() +"<hr>"+event.data);
    })

    /** 
     * Подключение к комет серверу. Для возможности принимать команды.
     * dev_id ваш публичный идентифиукатор разработчика
     */
    CometServer().start({dev_id:15 })
})

function sendMsg(){

	var text = $("#msgText").val();
	
    jQuery.ajax({
        url: "//comet-server.ru/doc/CometQL/simplePhpChat/sendMsgToChat.php",
        type: "GET",
        data:"text="+encodeURIComponent(text),
        success: function(){
            $("#msgText").val('');
        }
    });
}
</script>
</body>
</html>


Код для отправки сообщения из php
<?php 
// Подключаемся к комет серверу с логином и паролем для демо доступа (получить свои данные для подключения можно после регистрации на comet-server.ru )
// Логин 15
// Пароль lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8
// База данных CometQL_v1
$link = mysqli_connect("app.comet-server.ru", "15", "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8", "CometQL_v1");

// Отправляем сообщение в канал
mysqli_query (  $link, "INSERT INTO pipes_messages (name, event, message)VALUES('SimplePhpChat', '', '".mysqli_real_escape_string($link,htmlspecialchars($_GET['text']))."' );" );


Демо работы чата здесь.
Тут ещё один пример чата, но в нём php сервер вообще не используется, всю работу выполняет comet сервер. А здесь пример чата с авторизацией на комет сервере.

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


  1. Borro
    21.12.2015 10:03
    +1

    Есть еще модуль для nginx — nginx-push-stream-module


    1. Levhav
      21.12.2015 10:10

      Спасибо, добавил в статью.


  1. Ninjak
    21.12.2015 12:38
    +1

    а socket.io нынче уже и не комет-сервер? ;)


    1. Fesor
      21.12.2015 13:39
      +2

      меня больше удивляет использование термина «комет сервер» в 2015-ом. А что до socket-io, к пулингу оно прокидывается только как фэлбэк, когда сокеты использовать не выходит.


    1. Levhav
      21.12.2015 14:02

      На википедии сказано что socet.io это библиотека.

      Socket.IO — JavaScript библиотека для веб-приложений и обмена данными в реальном времени. Состоит из двух частей: клиентской, которая запускается в браузере и серверной для node.js

      В то время как приведённые в таблице комет сервера это законченные готовые приложения которые не надо доделывать для того что бы начать работать.


      1. AlexGx
        21.12.2015 15:38
        +1

        В то время как приведённые в таблице комет сервера это законченные готовые приложения которые не надо доделывать для того что бы начать работать.

        Использовал 3 реализации из вашей таблицы, в каждом из случаев приходилось доделывать, докручивать, писать репорты и учавствовать в баг фиксах. Возможно изза схожих проблем вы и занялись реализацией своего решения.


        1. Levhav
          21.12.2015 16:39

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


          1. Fesor
            21.12.2015 19:10

            Так все же, в чем преимущества относительно варианта с socket-io который используют десятки тысяч разработчиков по всему миру и который покрывает 95% юзкейсов возникающих при организации реалайтм взаимодействия клиента и сервера?


            1. Levhav
              22.12.2015 04:28

              Порог вхождения ниже. socket-io невозможно использовать без знания JavaScript в то время как у других комет серверов есть api под разные языки программирования.
              Да и вообще сравнивать библиотеку для реализации комет сервера и готовый комет сервер это примерно тоже что удивляться почему люди используют chrome а не пишут свою обёртку для Blink


              1. Fesor
                22.12.2015 11:04

                По вашей же аналогии вы сейчас пишете свой блинк, хотя могли сделать это дело на базе socket-io. Да и на гитхабе достаточно готовых «сервачков», ну и ваше же решение на socket-io вопервых и писать проще и скейлить чуть что удобнее (в последних версиях socket-io доступна синхронизация инфы между процессами).

                p.s. я по сути не сравниваю решения, меня интересует какой лично мне профит рассматривать ваше решение если есть socket-io. Написать простенький бродкаст сервер можно даже не зная javascript. Я не вижу явно преимуществ, вы же не описали этот момент.


                1. Levhav
                  22.12.2015 11:55

                  Да я написал всё с нуля на C++, мог бы для этого использовать и socet.io но не стал так как это был хобби проект и я использовал то что считал интересным а не то что было проще.

                  • Так как это сервис его могут использовать пользователи шаред хостинга которых очень много и которые не могут использовать тот же socet.io не арендуя vds.
                  • Для сайтов с небольшой посещаемостью оно бесплатно. Для более крупных сайтов сравнимо по цене с арендой vds но не требует навыков администрирования vds.
                  • Здорово экономит время так как его не надо дописывать. Оно готово для работы сразу. И в него встроено всё что необходимо для решения почти любых задач. А для остального можно просто обратися в поддержку и запросить новый функционал.
                  • Позволяет сэкономить время и деньги на начальных этапах развития проекта когда надо реализовать максимум функционала за минимум времени силами не JavaScript программистов (в среднем php программист получает меньше чем JavaScript программист).
                  • Для бизнеса дешевле и быстрее купить готовый продукт чем нанимать NodeJS специалиста так как моё решение (не как сервис а как программа для размещения на своих серверах ) стоит примерно как 2 недели работы хорошего NodeJS программиста.


                  Но если вы уже знаете nodeJs, умеете администрировать vds и не пытаетесь экономить на хостинге используя сверх дешёвые тарифы шаред-хостинга то вы вероятно не входите в целевую аудиторию моего проекта.


  1. AlexGx
    21.12.2015 15:32

    Забыли про WAMP и различные роутеры и клиенты реализующие его.