Рабочая группа 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')
В ответ сервер должен сначала выразить готовность посылать события, отправив заголовок:
Т.е каждое событие это блок из Event:имя события\n и данных. Каждое поле данных пишется на отдельной строке и имеет имя, здесь: "data". После двоеточия ставится пробел. События разбиваются двойным переводом строки.
На момент написания, Opera 9.2 поддерживает только имя поля "data", хотя по спецификации можно указать любое.
Если поле с одним именем повторяется, то данные сливаются с переводом строки. Например, здесь поле data="1\n2":
Event: someEvent
data: 1
data: 2
Так что многострочные данные тоже можно передавать через event source.
Браузер соединяется с сервером, как только в документе появляется 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 удобнее.
многострочные данные тоже можно передавать через event source.