Javascript.RU

HTML5 Event-source, Opera

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/server-sent-events.

Рабочая группа WHATWG по доработке HTML предложила свой стандарт для получения событий с сервера в HTML 5.0. Для этого в нем предусмотрен специальный элемент event-source, который
реализован в Opera 9+, и предоставляет довольно удобный способ реализации событий с сервера.

Тут будут сообщения, если браузер - Opera 9+

Чтобы Ваш HTML проходил валидацию, да и вообще для удобства, лучше не ставить этот элемент в разметку, а манипулировать им при помощи javascript.

У элемента event-source есть атрибут src и метод addEventSource, которые говорят браузеру соединиться с указанным URL и принимать оттуда события. Например,

var el = document.createElement("event-source")
el.setAttribute('id', 'events')
el.setAttribute('src', 'server.php')

В ответ сервер должен сначала выразить готовность посылать события, отправив заголовок:

header("Content-Type: application/x-dom-event-stream");

Далее сервер присылает данные в специальном формате вида:

Event: sessionid
data: RH7iaoUoq5ict7Z0lw3YaA

Event: connect
data: avvdw

Event: connect
data: test

Event: ping
data: pong

Т.е каждое событие это блок из Event:имя события\n и данных. Каждое поле данных пишется на отдельной строке и имеет имя, здесь: "data". После двоеточия ставится пробел. События разбиваются двойным переводом строки.

На момент написания, Opera 9.2 поддерживает только имя поля "data", хотя по спецификации можно указать любое.

Если поле с одним именем повторяется, то данные сливаются с переводом строки. Например, здесь поле data="1\n2":

Event: someEvent
data: 1
data: 2

Так что многострочные данные тоже можно передавать через event source.

Серверный код для примера очень прост:

header("Content-Type: application/x-dom-event-stream");

ob_implicit_flush(true);
while (@ob_end_flush()) {}

for( $i = 1; $i <= 5; $i++ ) {
	echo "Event: newMessage\n";
	echo "data: $i\n";
	echo "\n";
	sleep(1);
}

Каждое событие вызывает обработчик, который указывается в браузере через addEventListener:

el.addEventListener('newMessage', function(event) { alert(event.data) }, false);

Браузер соединяется с сервером, как только в документе появляется event-source, и отсоединяется - как только event-source уходит из документа.

Клиентский код примера выше:

...
// создать элемент event-source
var el = document.createElement("event-source")
el.setAttribute('src', '/server_push/event_source.php')
el.setAttribute('id', 'event_source')

// добавить обработчик события newMessage
var newMessageHandler = function(event) {
	var d = document.createElement('div')
	d.innerHTML = "data: "+event.data
	out.appendChild(d) // out - это div для вывода, определен ранее
}
el.addEventListener('newMessage', newMessageHandler, false);

// эта функция добавляет event-source в документ, браузер стучится на сервер
var startIt = function() { 
	document.body.appendChild(el) 
}
// эта функция убирает event-source, браузер отключается от сервера
var stopIt = function() { 
	document.body.removeChild(el) 
}

// запускаем, ограничиваем подключение 10 секундами
startIt()
setTimeout(stopIt, 10000)

В event-source принципиально не предусмотрена обработка ошибок. Единственный реальный способ ее сделать - регулярно слать ping-пакеты с сервера. Так, чтобы если клиент не получил ping-пакет вовремя - регистрируем задержку, прошел таймаут без пакетов - связь считаем нарушенной.

Никаких HTTP-заголовков, статусов с сервера, уведомлений об обрыве связи нет. В этом смысле Бесконечный IFrame удобнее.

  • минимальная задержка и трафик
  • нет индикации загрузки
  • данные нельзя сжимать
  • Opera only
  • нет обработки ошибок, только ping-пакеты

Автор: Аркадий (не зарегистрирован), дата: 20 марта, 2009 - 23:21
#permalink

многострочные данные тоже можно передавать через event source.


Автор: maxbarbul, дата: 6 января, 2010 - 13:08
#permalink

а почему данные приходят в двойном экземпляре? (пример на этой странице)

про бовал у себя на localhost приходят также в двойном экземпляре, только порядок другой и первый элемент не приходит, получается след результат:

data: 2
data: 3
data: 4
data: 5
data: 2
data: 3
data: 4
data: 5


Автор: oygemor, дата: 23 декабря, 2012 - 19:58
#permalink

favicon?


Автор: Denisko-Redisko, дата: 3 июля, 2010 - 05:29
#permalink

Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
10 + 5 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Реклама
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum