Чтение онлайн

ЖАНРЫ

JavaScript. Подробное руководство, 6-е издание
Шрифт:

// И установить долгоживущее соединение

connect;

// Если соединение было закрыто обычным образом, ждать секунду

// и попробовать восстановить соединение

function reconnect {

if (aborted) return; // He восстанавливать после

// принудительного
прерывания

if (xhr.status >= 300) return;

// He восстанавливать после ошибки

setTimeout(connect, retrydelay); // Ждать и повторить попытку

};

// Устанавливает соединение

function connect {

charsReceived = 0; type = null; xhr.open("GET", url);

xhr.setRequestHeader(“Cache-Control", "no-cache");

if (lastEventld)

xhr.setRequestHeader("Last-Event-ID", lastEventld);

xhr.send;

}

// При получении данных обрабатывает их и вызывает обработчик onmessage.

// Эта функция реализует работу с протоколом Server-Sent Events

function processData {

if (!type) { // Проверить тип ответа, если это еще не сделано

type = xhr.getResponseHeader(’Content-Type’);

if (type !== "text/event-stream") {

aborted = true;

xhr.abort;

return;

}

}

// Запомнить полученный объем данных и извлечь только ту часть ответа,

// которая еще не была обработана,

var chunk = xhr.responseText.substring(charsReceived);

charsReceived = xhr.responseText.length;

// Разбить текст на строки и обойти их в цикле.

var lines = chunk.replace(/(\r\n|\r|\n)$/,"").split(/\r\n|\r|\n/);

for(var і = 0; і < lines.length; i++) {

var line = lines[i], pos = line.indexOf(":"), name.value="";

if (pos == 0) continue; // Игнорировать комментарии

if (pos > 0) { // поле name:value

name = line.substring(0,pos);

value = line.substring(pos+1);

if (value.charAt(O) == " ") value = value.substrings);

}

else name = line; //
только поле name

switch(name) {

case "event": eventName = value; break;

case "data": data += value + "\n"; break;

case "id": lastEventld = value; break;

case "retry": retrydelay = parselnt(value) || 1000; break;

default: break; // Игнорировать любые другие строки

}

if (line === "") { // Пустая строка означает отправку события

if (evtsrc.onmessage && data !== "") {

// Отсечь завершающий символ перевода строки

if (data.charAt(data.length-1) == "\n")

data = data.substrings, data.length-1);

evtsrc.onmessage({ // Имитация объекта Event

type: eventName, // тип события

data: data, // данные

origin: url // происхождение данных

});

}

data = "";

continue;

}

}

}

};

}

Завершим описание архитектуры Comet примером серверного сценария. В примере 18.17 приводится реализация HTTP-сервера на серверном JavaScript, который выполняется под управлением интерпретатора Node (раздел 12.2). Когда клиент обращается к корневому URL «/», сервер отправляет ему реализацию клиента чата, представленную в примере 18.15, и реализацию имитации, представленную в примере 18.16. Когда клиент выполняет GET-запрос по URL-адресу «/chat», сервер сохраняет поток ответа в массиве и поддерживает соединение открытым. А когда клиент выполняет POST-запрос к адресу «/chat», сервер интерпретирует тело запроса как текст сообщения и добавляет префикс «data:», как того требует протокол Server-Sent Events, во все открытые потоки сообщений. Если вы установите интерпретатор Node, вы сможете запустить этот пример сервера локально. Он прослушивает порт 8000, поэтому после запуска сервера в броузере необходимо будет указать адресчтобы соединиться с сервером и начать общение с самим собой.

Поделиться с друзьями: