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 - 22:21
#permalink

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


 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

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

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

Интерфейсы

Все об AJAX

Оптимизация

Разное

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

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