Что такое отправленные сервером события (SSE)
В спецификации говорится: «API для открытия HTTP-соединения для получения push-уведомлений с сервера в форме событий DOM. API разработан таким образом, что его можно расширить для работы с другими схемами push-уведомлений, такими как Push SMS».
Отправленные сервером события работают по HTTP и предоставляют интерфейс «EventSource». Веб-приложения могут подписаться на EventSource и получать обновления со стороны сервера, т. Е. Сервер может передавать данные клиентам по мере необходимости. Почему не Websockets?
Веб-сокеты очень полезны при разработке различных приложений, таких как приложения чата, игры и т. Д. где связь происходит по двунаправленному каналу между клиентом и сервером. Однако в таких приложениях, как Stock ticker, Feed reader, сервер отвечает клиентом сообщением, а клиент получает его и показывает его пользователю. В таких приложениях клиент не часто публикует сообщение. В этих сценариях SSE очень полезны. Другое преимущество использования SSE над Websockets состоит в том, что он работает по HTTP, что означает, что он не требует специального протокола или какой-либо реализации на стороне сервера.
Пример SSE с ColdFusion
Как упоминалось ранее, веб-приложение может подписаться на сервер с помощью интерфейса EventSource. Итак, в моем JavaScript у меня есть этот код:
var source = new EventSource('outputMessages.cfm');
Это очень просто. Мы подписываемся на серверный код, который называется outputMessages.cfm. После успешного подключения клиент может начать получать сообщения с сервера. Объект EventSource имеет следующие прослушиватели событий: сообщение, открытие и ошибка.
source.addEventListener('message', function(e){
document.body.innerHTML += e.data + "<br>";
});
source.addEventListener('open', function(e){
alert('open')
}, false);
source.addEventListener('error', function(e){
if (e.eventPhase == EventSource.CLOSED) {
alert('closed')
}
}, false);
Затем объект EventSource может запускать эти сценарии в фоновом режиме, не блокируя какие-либо сценарии. После установления соединения с сервером будет вызвано событие onopen, и клиент будет готов к приему сообщений с сервера. Если сервер ответит сообщением, будет вызвано событие «onmessage» и будет выполнен соответствующий ему обработчик события. Событие ‘onerror’ будет вызвано, когда сервер завершит свое выполнение, и, как это наблюдается в приведенном выше коде, состояние объекта EventSource будет установлено на CLOSED.
Объект EventSource ожидает, что сервер отправит данные с текстом / потоком событий MIME-типа, и данные будут отправлены в следующем формате:
data: Your message here \n\n
Он ожидает строку «data:», затем сообщение, а затем символ конца строки. Дополнительный символ конца строки отмечает конец сообщения, т.е. пользователи могут отправлять таким образом несколько строк данных, а затем отправлять символ конца строки, чтобы отметить конец сообщения. Следующий файл cfm делает именно это:
<cfcontent type="text/event-stream">
<cfsetting requesttimeout="60">
<cffunction name="sendData">
<cfoutput>data: #timeFormat(now(), "medium")# #Chr(10)#</cfoutput>
<cfoutput>data: End of this message #Chr(10)#</cfoutput>
<cfoutput>#Chr(10)#</cfoutput>
<cfflush>
</cffunction>
<cfloop from="1" to="50" index="i">
<cfset sendData()>
<cfthread action="sleep" duration="1000"/>
</cfloop>
Тег cfcontent устанавливает для типа MIME значение text / event-stream, а затем для requestTimeout устанавливается значение 60 секунд. Функция sendData вызывается 50 раз (в cfloop) и будет выводить данные клиенту каждую секунду. Третий cfoutput отправляет только символ конца строки, отмечающий конец сообщения.
Цикл будет выполняться в течение 50 секунд, и как только обслуживаемая сторона программы завершит свое выполнение, состояние объекта EventSource будет установлено на CLOSED. Затем клиент восстанавливает соединение с сервером через 3 секунды, и тот же цикл будет выполнен снова.
SSE могут оказать большую помощь в уменьшении пропускной способности, и в случаях, когда клиент хочет опубликовать некоторые данные, тогда объект XHR пригодится.