diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/api/server-sent_events/using_server-sent_events | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/web/api/server-sent_events/using_server-sent_events')
-rw-r--r-- | files/ru/web/api/server-sent_events/using_server-sent_events/index.html | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/files/ru/web/api/server-sent_events/using_server-sent_events/index.html b/files/ru/web/api/server-sent_events/using_server-sent_events/index.html new file mode 100644 index 0000000000..8aeb349c50 --- /dev/null +++ b/files/ru/web/api/server-sent_events/using_server-sent_events/index.html @@ -0,0 +1,186 @@ +--- +title: Using server-sent events +slug: Web/API/Server-sent_events/Using_server-sent_events +translation_of: Web/API/Server-sent_events/Using_server-sent_events +--- +<p>{{DefaultAPISidebar("Server Sent Events")}}</p> + +<div class="summary"> +<p>Разрабатывать web-приложения, использующие <a href="/en-US/docs/Web/API/Server-sent_events">Server-Sent Events</a> намного проще, чем с использованием websockets. Нужно всего лишь немного кода на стороне сервере, чтобы переправлять события web-приложению, но клиентская часть кода для обработки этих событий работает почти точно так же, как и для любых других событий.</p> +</div> + +<h2 id="Получение_событий_от_сервера">Получение событий от сервера</h2> + +<p>Server-Sent Event API содержится внутри интерфейса {{domxref("EventSource")}}. Чтобы открыть соединение с сервером для начала записи событий, которые он присылает, необходимо создать новый объект <code>EventSource</code>, который будет указывать на URI скрипта, который создает события. Например:</p> + +<pre class="brush: js">const evtSource = new EventSource("ssedemo.php");</pre> + +<p>Если файл с генератором событий размещен на другом домене, то должен быть создан новый объект <code>EventSource</code> в который следует передать помимо URI еще и словарь опций. Например, если предположить, что клиентский скрипт находится на <code>example.com</code>:</p> + +<pre class="brush: js"><code>const evtSource = new EventSource("//api.example.com/ssedemo.php", { withCredentials: true } ); </code> +</pre> + +<p>Как только вы создали экземпляр <code>EventSource</code>, вы можете начать прослушивание сообщений с сервера, добавив обработчик для события {{event("message")}} :</p> + +<pre class="brush: js">evtSource.onmessage = function(event) { + const newElement = document.createElement("li"); + const eventList = document.getElementById('list'); + + newElement.innerHTML = "message: " + event.data; + eventList.appendChild(newElement); +} +</pre> + +<p>Этот код прослушивает входящие сообщения (то есть уведомления от сервера, на которых нет поля <code>event</code>) и добавляет текст сообщения в список в HTML-документе.</p> + +<p>Вы также можете прослушивать события, используя <code>addEventListener()</code>:</p> + +<pre class="brush: js"><code>evtSource.addEventListener("ping", function(event) { + const newElement = document.createElement("li"); + const time = JSON.parse(event.data).time; + + newElement.innerHTML = "ping at " + time; + eventList.appendChild(newElement); +});</code></pre> + +<p>Этот код аналогичен коду выше, за исключением того, что он будет вызываться автоматически всякий раз, когда сервер отправляет сообщение с полем <code>event</code>, установленным в «ping»; затем он парсит JSON в поле <code>data</code> и выводит эту информацию.</p> + +<h2 id="Отправка_событий_с_сервера">Отправка событий с сервера</h2> + +<p>Код на стороне сервера, который отправляет события, должен отвечать, используя MIME-тип <code>text/event-stream</code>. Каждое уведомление отправляется в виде блока текста, оканчивающегося парой новых строк (<code>\n</code>) . Подробнее о формате потока событий см. {{ anch("Event stream format") }}.</p> + +<p>{{Glossary("PHP")}} код, который мы используем для примера приведен ниже:</p> + +<pre class="brush: php">date_default_timezone_set("America/New_York"); +header('Cache-Control: no-cache'); +header("Content-Type: text/event-stream\n\n"); + +$counter = rand(1, 10); +while (1) { + // Every second, send a "ping" event. + + echo "event: ping\n"; + $curDate = date(DATE_ISO8601); + echo 'data: {"time": "' . $curDate . '"}'; + echo "\n\n"; + + // Send a simple message at random intervals. + + $counter--; + + if (!$counter) { + echo 'data: This is a message at time ' . $curDate . "\n\n"; + $counter = rand(1, 10); + } + + ob_end_flush(); + flush(); + sleep(1); +} +</pre> + +<p>Приведенный выше код генерирует событие каждую секунду с типом события «ping». Данные каждого события - это объект JSON, содержащий метку времени ISO 8601, соответствующую дате, когда было сгенерировано событие. Через случайные интервалы отправляется простое сообщение (без типа <code>event</code>).</p> + +<div class="note"> +<p><strong>Примечание</strong>: Вы можете найти полный пример, который использует код, показанный в этой статье на GitHub - см. <a href="https://github.com/mdn/dom-examples/tree/master/server-sent-events">Simple SSE demo using PHP.</a></p> +</div> + +<h2 id="Обработка_ошибок">Обработка ошибок</h2> + +<p>Когда возникают проблемы (такие как тайм-аут ответа сети или проблемы, связанные с <a href="/en-US/docs/HTTP/Access_control_CORS" title="/en-US/docs/HTTP/Access_control_CORS">контролем доступа</a>), тогда генерируется событие <code>error</code>. Вы можете обработать это событие программно, реализовав метод <code>onerror</code> для объекта <code>EventSource</code>:</p> + +<pre class="brush: js">evtSource.onerror = function(error) { + console.error("⛔ EventSource failed: ", error); +}; +</pre> + +<h2 id="Закрытие_потоков_событий">Закрытие потоков событий</h2> + +<p>По умолчанию, если соединение между клиентом и сервером закрывается, то соединение сбрасывается. Прервать соединение можно с помощью метода <code>.close()</code>.</p> + +<pre class="brush: js">evtSource.close();</pre> + +<h2 id="Формат_потока_событий">Формат потока событий</h2> + +<p>Поток событий представляет из себя простой поток текста, который должен иметь кодировку <a href="https://developer.mozilla.org/en-US/docs/Glossary/UTF-8">UTF-8</a>. Сообщения в потоке событий разделяются парой символов новой строки. Двоеточие, как первый символ строки считается комментарием и игнорируется.</p> + +<div class="note"><strong>Примечание:</strong> Строка комментария может использоваться, чтобы предотвратить тайм-аут соединений; сервер может периодически отправлять комментарий, чтобы поддерживать соединение.</div> + +<p>Каждое сообщение содержит одну или более строчек текста, которые перечиляют поля этого сообщения. Каждое имеет свое имя, за которым следует двоеточие, после которого идут текстовые данные для значения этого поля. </p> + +<h3 id="Поля">Поля</h3> + +<p>Каждое полученное сообщение имеет некоторую комбинацию следующих полей, по одному на строку:</p> + +<dl> + <dt><code>event</code></dt> + <dd>Строка, идентифицирующая тип описанного события. Если <code>event</code> указан, то событие будет отправлено в браузер слушателю для указанного имени события. Исходный код сайта должен использовать <code>addEventListener()</code> для прослушивания именованных событий. Обработчик <code>onmessage</code> вызывается, если для сообщения не указано имя события.</dd> + <dt><code>data</code></dt> + <dd>Поле данных для сообщения. Когда <code>EventSource</code> получает несколько последовательных строк, начинающихся с <code>data:</code>, <a href="http://www.w3.org/TR/eventsource/#dispatchMessage">он объединяет их</a>, вставляя символ новой строки между каждой из них. Последние переводы строки удаляются.</dd> + <dt><code>id</code></dt> + <dd>Идентификатор события для установки значения последнего ID события для объекта <code><a href="/en/Server-sent_events/EventSource" title="en/Server-sent events/EventSource">EventSource</a></code>.</dd> + <dt><code>retry</code></dt> + <dd>Время переподключения, используемое при попытке отправить событие. Это должно быть целое число, указывающее время переподключения в миллисекундах. Если указано нецелое значение, поле игнорируется.</dd> +</dl> + +<p>Другия названия полей игнорируются.</p> + +<div class="note"><strong>Примечание:</strong> If a line doesn't contain a colon, the entire line is treated as the field name with an empty value string.</div> + +<h3 id="Примеры">Примеры</h3> + +<h4 id="Сообщения_с_данными">Сообщения с данными</h4> + +<p>В следующем примере отправлено три сообщения. Первый - это просто комментарий, так как он начинается с символа двоеточия. Как упоминалось ранее, это может быть полезно в качестве подтверждения активности, если сообщения могут отправляться не регулярно.</p> + +<p>Второе сообщение содержит поле данных со значением «some text». Третье сообщение содержит поле данных со значением «another message \n with two lines». Обратите внимание на специальный символ новой строки в значении.</p> + +<pre class="brush: json">: this is a test stream + +data: some text + +data: another message +data: +</pre> + +<h4 id="Именованные_события">Именованные события</h4> + +<p>Данный пример отправляет именованные события. У каждого из них есть имя события, указанное в поле <code>event</code>, и поле <code>data</code>, значением которого является соответствующая строка JSON с данными, необходимыми для клиента, чтобы реагировать на событие. Поле <code>data</code> может, конечно, содержать любые строковые данные; это не обязательно должен быть JSON.</p> + +<pre class="brush: json">event: userconnect +data: {"username": "bobby", "time": "02:33:48"} + +event: usermessage +data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."} + +event: userdisconnect +data: {"username": "bobby", "time": "02:34:23"} + +event: usermessage +data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."} +</pre> + +<h4 id="Смешивание_и_сопоставление">Смешивание и сопоставление</h4> + +<p>Вам не нужно использовать только неназванные сообщения или именованные события. Вы можете смешать их вместе в одном потоке событий.</p> + +<pre class="brush: json">event: userconnect +data: {"username": "bobby", "time": "02:33:48"} + +data: Here's a system message of some kind that will get used +data: to accomplish some task. + +event: usermessage +data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div> +<h3 id="EventSource"><code>EventSource</code></h3> + +<div> + + +<p>{{Compat("api.EventSource")}}</p> +</div> +</div> |