HTML5 и события сервера (обновлено)

    Помимо уже упомянутого мною двунаправленного коммуникационного канала известного как WebSocket, HTML5 включаетв себя также сервер-push технологию Server-Sent Events (SSE). В то время как WebSocket широко обсуждается, доступно множество реализаций серверов WebSocket, технология уже почти в полном объеме доступна в браузере Google Chrome, SSE, по большей части остаются в тени.

    Мы привыкли что HTTP ограничен моделью запрос-ответ, что значит: клиент посылает запрос HTTP и ожидает на него HTTP-ответ. По сути, сервер не может сообщить что-либо клиенту до тех пор пока клиент его его «не попросит». Даже для такой тривиальной вещи как онлайн статус пользователя, нам надо прибегать к различным уловкам. Ну вы знаете – неугомонная изобретательность энтузиастов породила множество таких решений, на что есть собирательное имя Comet. Впрочем, цитируя экспертов: «Comet есть не что иное как гигантский хак». Похоже, HTML 5 призван обогатить нас нативными возможностями, на смену ныне используемому Comet. В случе SSE, HTML5 предоставляет API для открытия специального HTTP соединения для принятия уведомлений со стороны сервера. Взгляните, на то какой простой интерфейс:

    var source = new EventSource('updates.php');
    source.onmessage = function (event) {
    alert(event.data);
    };


    На стороне сервера скрипт посылает сообщения в следующем формате (ожидается MIME-тип text/event-stream):
    data: TROLOLOLOLOLOLOLOLOLOLO
    data: Lorem ipsum dolor sit amet
    data: consectetur adipiscing elit.
    data: Vestibulum rutrum nisi in diam dapibus eget tempor mauris sollicitudin


    Более того, нам даже не нужен бесконечный цикл в скрипте. После открытия соединения будет так, словно скрипт запрашивается на исполнение автоматически.
    <?php
    header("Content-Type: text/event-stream\n\n");
    echo 'data: ' . time() . "\n";
    ?>


    Ну и как это работает? Клиент открывает поток событий через создание EventSource, принимающего в параметре адрес источника событий. Обработчик события onmessage будет вызываться каждый раз при поступлении новых данных из источника. Как вы видите, имея AJAX мы можем асинхронно обращаться из клиента к серверу и, наоборот, через SEE обращаться из сервера к клиенту, опять же асинхронно.

    Помимо прочего HTML5 описывает такую технологию как WebWorker. Она позволяет запускать скрипты на исполнение в фоне и независимо друг от друга. Так что, если у вас случиться превышение допустимого лимита на открытые соединений в браузере из-за множества открытых EventSource, не беда — это легко решаемо. В каждом случае вы ссылаетесь на один и тот же WebWorker, который и обслуживает EventSource соединение.
    И что, все это реально доступно для использования? SSE реализованы в девелоперской версии Google Chrome 6, в Safari 5.0 и в Opera 9.x. Впрочем, последняя реализация не совсем то, что я показывалв примерах выше. Под Оперой вы должны создать специальный элемент в HTML, на который затем «повесите» слушателя (listener).

    <event-source src="events.php" />


    Более того, со стороны сервера могут приходить события, адресованные различным слушателям

    document.getElementsByTagName("event-source")[0]
    .addEventListener("server-time", function (event) {
    alert(event.data);
    }, false);


    Контроллер выглядить примерно так:

    <?php
    header("Content-Type: application/x-dom-event-stream");
    echo "Event: server-time\n";
    echo "data: " . time() . "\n";
    flush();
    ?>


    Далее я сделал пример, с помощью которого вы можете посмотреть как SSE работают в вашем браузере. Так не использовается консоль, так что поступающие с сервера сообщения не надо нигде искать, вы их увидите на странице.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

    Комментарии 16

      0
      А вот тут есть небольшой туториал с двумя демо как все это работает…
        0
        Да, и ссылки для скачки билдов Chrome в котором все это работает.
          0
          Упс, я невнимательно дочитал пост — у вас уже была эта ссылка
          –3
          >text/event-stream
          нагородили своих поганых велосипедов. а без этого г*вна никак нельзя?
            +1
            А что тут не так?
              0
              Признаться, еще недавно это было x-dom-event-stream и народ юзал именно так SSE под Оперой. Теперь же они остановились на text/event-stream (хотя это по прежнему в обсуждении). Когда всеже определятся, передадут в IANA на регистрацию и вот тогда оно таки станет стандартом. А пока типа «велосипед»
                0
                А чего вы хотели, если html5 еще в драфте?
              0
              Все отлично, только пара замечаний.
              Работает и в Safari 5, а что бы проверить работу надо открыть консоль :)

              code.bocoup.com/event-source/event-source-1.html
              code.bocoup.com/event-source/event-source-2.html
                –1
                У меня ссылки не открываются…
                  0
                  Белая страница? :)
                  Так надо в консоль смотреть.
                    0
                    упс, сглупил. Console.log…
                0
                Поясните пожалуйста, получает браузер будет просто с каким-то интервалом отправлять запрос? (если без цикла)
                Интервал как-то выставляется, или все на усмотрение браузера? В чем тогда отличие с обычной кучкой ajax запросов, на которые таймер навешан?

                Или же, все таки, в браузер встроят какой-то приемник, аналог сервера (как в opera unite), который сможет принимать запросы от клиентов (роль которых будет выполнять сервер)?
                  0
                  Я так думаю, что он просто слушает 80 порт (default) сервера, это похоже на WebSocket, только последний коннектится отдельно.
                    0
                    Мне тоже не попадалось пояснений со стороны разработчиков Google. Но народ как-то сходится на мнении, что Chrome делает что-то вроде нативного polling. Так что действительно не ясно, есть ли какие-либо плюсы в такой имплементации. Под Оперой я вижу — там просто цикл while(true) — stackoverflow.com/questions/2561764/use-a-x-dom-event-stream-stream-in-javascript

                    Впрочем, это частные решения. В стандарте (draft) ничего подобного я не видел, но любые реализации на его основе как-бы должны дать следующие преимущества перед привычным Comet:
                    Using this API rather than emulating it using XMLHttpRequest or an iframe allows the user agent to make better use of network resources in cases where the user agent implementor and the network operator are able to coordinate in advance. Amongst other benefits, this can result in significant savings in battery life on portable devices.
                    0
                    опера вроде как поддерживает server side events my.opera.com/WebApplications/blog/show.dml/438711
                      0
                      Теперь добавил в пример для демонтрации Server-Sent Events — помимо нативных Chrome, Safari, Opera еще и эмулятор для Firefox. Смотреть здесь
                      sapid.sourceforge.net/ssetest/

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