搜索
首页web前端js教程服务器范围事件

Server-sent Events

核心要点

  • 服务器发送事件 (SSE) 是一种利用流将数据和/或 DOM 事件从服务器推送到客户端的方法,非常适用于需要定期更新数据的情况,例如体育比分或股票行情。
  • 创建 EventSource 对象允许您订阅事件流,并能够处理打开、消息和错误事件。
  • 从服务器发送事件需要使用 Content-type 头部(值为 text/event-stream)和 UTF-8 字符编码来提供内容。服务器发送事件的语法包括数据、事件类型、事件标识符和重试间隔。
  • 事件处理可以使用 onmessage 函数(仅用于发送消息事件的应用程序),但 addEventListener 方法对于处理自定义事件更灵活。
  • 大多数现代浏览器(包括 Chrome、Firefox 和 Safari)都支持服务器发送事件 (SSE),但 Internet Explorer 不支持。对于需要支持所有浏览器的应用程序,WebSockets 或长轮询可能更合适。
  1. 简介
  2. 订阅流:EventSource 对象
  3. 从服务器发送事件
    1. 发送消息事件
    2. 发送自定义事件
    3. 使用重试间隔管理重新连接
    4. 使用 id 字段设置唯一标识符
  4. 处理事件
  5. 处理错误
  6. 浏览器实现差异
  7. 浏览器支持和回退策略

假设您国家的国家篮球队正在参加世界篮球锦标赛。您想关注比赛,但由于比赛时间与您的工作时间冲突,无法观看。

幸运的是,您的国家新闻服务拥有一个非常出色的 Web 开发团队。他们构建了一个体育信息滚动显示器,每当出现犯规或得分时都会更新。您访问一个 URL,更新就会直接推送到您的浏览器。当然,您会想知道他们是如何做到的。答案是:服务器发送事件。

服务器发送事件是一种使用流将数据和/或 DOM 事件从服务器推送到客户端的方法。它适用于股票行情、体育比分、航班追踪、电子邮件通知——任何需要定期更新数据的情况。

等等! 我听到您说,我们不能已经使用 XMLHttpRequest 或 WebSockets 来做到这一点吗?是的,可以。但是,这样做需要扩展这些对象来实现 EventSource 本身的功能。

服务器端注意事项

由于服务器发送事件是数据流,因此它们需要长期连接。您需要使用能够处理大量同时连接的服务器。当然,事件驱动服务器特别适合流式传输事件。这些包括 Node.js、Juggernaut 和 Twisted。对于 Nginx,可以使用 nginx-push-stream-module 模块。但是,服务器配置不在本文讨论范围之内,并且会因您使用的服务器而异。

让我们看看如何使用 EventSource 对象订阅流。然后,我们将看看如何发送和处理事件。

订阅事件流:EventSource 对象

创建 EventSource 对象很简单。

var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});

EventSource 构造函数最多接受两个参数:

  • 一个 URL 字符串(必需);以及
  • 一个 可选 的字典参数,用于定义 withCredentials 属性的值。

字典在语法上类似于对象,但它们实际上是具有定义的名称-值对的关联数据数组。在本例中,withCredentials 是唯一可能的字典成员。其值可以是 true 或 false。(要了解有关字典的更多信息,请参阅 Web IDL 规范。)

仅当需要用户凭据(cookie)的跨域请求时,才需要包含字典参数。到目前为止,没有浏览器支持跨域 EventSource 请求。因此,我们不会在示例中包含第二个参数。

当 EventSource 连接打开时,它将触发一个 open 事件。我们可以通过设置 onopen 属性来定义一个处理该事件的函数。

var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}

如果我们的连接出现问题,将触发一个错误。我们可以使用 onerror 属性为这些事件定义一个处理程序函数。我们将在“处理错误”部分讨论一些错误事件的原因。

evtsrc.onerror = function(openevent){
    // 发生错误时执行的操作
}

流式事件默认为消息事件。要处理消息事件,我们可以使用 onmessage 属性来定义一个处理程序函数。

evtsrc.onmessage = function(openevent){
    // 接收到消息事件时执行的操作
}

我们还可以使用 addEventListener() 来监听事件。这是处理自定义事件的唯一方法,正如我们将在“处理事件”部分看到的那样。

var onerrorhandler = function(openevent){
    // 执行的操作
}
evtsrc.addEventListener('error',onerrorhandler,false);

要关闭连接,请使用 close() 方法。

evtsrc.close();

因此,我们创建了 EventSource 对象,并为打开、消息和错误事件定义了处理程序。但是,为了使此方法有效,我们需要一个流式传输事件的 URL。

从服务器发送事件

服务器发送事件是作为来自 URL 的流的一部分交付的文本片段。为了让浏览器将我们的数据视为流,我们必须:

  • 使用 Content-type 头部(值为 text/event-stream)来提供内容;
  • 使用 UTF-8 字符编码。

服务器发送事件的语法很简单。它由一个或多个冒号分隔的字段名称-值对组成,后跟一个换行符。字段名称可以包含四个可能的值之一。

  • data::要发送的信息。
  • event::正在分派的事件类型。
  • id::客户端重新连接时要使用的事件标识符。
  • retry::浏览器尝试重新连接到 URL 之前应经过多少毫秒。

其中,只有 data 字段是必需的。

发送消息事件

在此示例中,我们将发送一个事件来宣布我们的锦标赛比赛中哪些球队正在比赛。当浏览器接收到此文本时,它将分派一个消息事件。

var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});

data 字段的值将成为消息事件的 data 属性的值。如上所述,服务器发送事件默认为消息事件。但正如我们稍后将讨论的那样,我们还可以通过包含 event 字段来分派自定义事件。

我们还可以将几条数据作为单个事件发送。每块数据后面都应该跟着一个换行符(换行符、回车符或两者)。在这里,我们正在追加一个包含此游戏位置和出席人数的事件。

var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}

对于此事件,data 属性的值将是:Air Canada CentrenToronto, Ontario, CanadanAttendance: 19,800。

请注意事件之间的空行。为了让客户端接收事件,事件后面必须跟一个空行。注释以冒号开头。

发送自定义事件

除非我们另行指定,否则事件的类型为消息。为此,我们需要包含一个 event 字段。在下面的示例中,我们将向我们的流中添加两个 startingfive 事件,并将我们的数据作为 JSON 格式的字符串发送。

evtsrc.onerror = function(openevent){
    // 发生错误时执行的操作
}

在这里,我们需要监听 startingfive 事件而不是消息事件。但是,我们的 data 字段仍然会成为事件的 data 属性的值。

我们将在“处理事件”部分讨论 data 属性和 MessageEvent 接口。

管理连接和重新连接

现在,虽然服务器确实将事件推送到浏览器,但现实情况要细微一些。如果服务器保持连接打开,EventSource 请求将是一个扩展的请求。如果它关闭,浏览器将等待几秒钟,然后重新连接。例如,如果 URL 发送一个文件结束标记,则连接可能会关闭。

每个浏览器都设置了自己的默认重新连接间隔。大多数会在 3 到 6 秒后重新连接。但是,您可以通过包含 retry 字段来控制此间隔。retry 字段指示客户端在重新连接到 URL 之前应等待多少毫秒。让我们从上面的示例构建并更改我们的事件以包含 5 秒(5000 毫秒)的重试间隔。

evtsrc.onmessage = function(openevent){
    // 接收到消息事件时执行的操作
}

事件流可以保持活动状态,只要客户端已连接即可。根据您的架构和应用程序,您可能希望服务器定期关闭连接。

使用 id 字段设置唯一标识符

当浏览器重新连接到 URL 时,它将接收连接点处可用的任何数据。但是,对于游戏信息滚动显示器,我们可能希望让访问者了解他或她错过了什么。这就是为什么将 id 设置为每个事件的最佳实践。在下面的示例中,我们正在发送 id 作为得分事件的一部分。

var evtsrc = new EventSource('./url_of/event_stream/',{withCredentials:false});

其值应对于流是唯一的。在本例中,我们使用的是投篮得分的时间。

id 字段成为此事件对象的 lastEventId 属性。但它还有另一个用途。如果连接关闭,浏览器将在其下一个请求中包含一个 Last-Event-ID 头部。将其视为流的书签。如果存在 Last-Event-ID 头部,您可以调整应用程序的响应,以便仅发送在其之后的事件。

处理事件

如上所述,所有事件默认为消息事件。每个消息事件都有三个属性,由 MessageEvent 接口定义。

event.data
返回作为消息事件一部分发送的数据或消息。
event.origin
返回消息的来源,这通常是一个字符串,包含发送消息的方案(例如:http、https)、主机名和端口。
event.lastEventId
返回接收到的最后一个事件的唯一标识符。
每当触发消息事件时,我们的 onmessage 函数都将被调用。这对于您发送消息事件的应用程序来说效果很好。但是,如果您想发送得分或 startingfive 事件(如我们的示例中所示),其局限性就会变得显而易见。使用 addEventListener 更灵活。在下面的代码中,我们正在使用 addEventListener 处理 startingfive 事件。
var evtsrc = new EventSource('./url_of/event_stream/');
evtsrc.onopen = function(openevent){
    // 连接打开时执行的操作
}

(后续部分,由于篇幅限制,请分段提问。)

以上是服务器范围事件的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python还是JavaScript更好?Python还是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安装JavaScript?如何安装JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。

在Quartz中如何在任务开始前发送通知?在Quartz中如何在任务开始前发送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前发送任务通知在使用Quartz定时器进行任务调度时,任务的执行时间是由cron表达式设定的。现�...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)