前端开发中,数据传输是非常重要的环节,我们平常常用的是Ajax、WebSocket等技术来进行数据传输。但是此处我们想要详细介绍另一种优秀的技术——Server-Sent Events,以及与Ajax、WebSocket的比较分析。想必大家通过此文可以深入学习Server-Sent Events的基础知识、使用场景以及优缺点等。
什么是Server-Sent Events
在介绍Server-Sent Events之前,我们先回顾一下现有的技术,Ajax和WebSocket。Ajax技术实现的主要应用场景是前后端异步通信,也就是通过AJAX技术来实时的对数据进行更新,而WebSocket则是一种全双工通信的协议,能够实现实时信息传递,相较于Ajax,WebSocket通讯协议更加灵活,带宽占用更低。
Server-Sent Events(SSE)技术则介于两者之间,提供了基于HTTP的服务器发送事件,通过浏览器与服务器端进行单向通信。与WebSocket不同的是,SSE是在单个长连接上进行消息传递的,而不必创建每个消息都要创建一个新的HTTP请求的问题。 SSE尤其适用于Web应用程序的实时性更新,比如股票市场行情。
具体而言,SSE为服务器向客户端推送事件提供了技术支持。在使用SSE时,客户端向服务端发起一个HTTP连接请求,然后服务器将不断传输更新到客户端响应中,直到客户端关闭链接。
SSE有三个核心组件: EventSource object
、Server Sent Events 格式
和Event Type
。通过EventSource object
,客户端获得了服务端的数据推送,在数据上传到客户端的过程中,EventSource object
会对接收到的数据进行处理。SSE发送的消息格式是以data:
的文本行开头的。它拥有基本的事件类型和可以动态扩展的事件类型,通过不同事件类型的划分来分类组织服务器事件。事件类型可以用于服务端的事件分类或者标识客户端的不同的事件响应处理。例如,您可以在服务端定义一个名为“login”的事件,如果客户端接收到了这个事件,说明客户端已经登录成功。
Server-Sent Events与Ajax、WebSocket区别分析
我们可以通过对比分析,找出SSE与Ajax、WebSocket的不同之处。
1. 单向通信模式
SSE与WebSocket的通讯模式是单向通讯模式,也就是数据仅仅从服务端流向客户端,数据的传输仅仅是服务端通过HTTP向客户端推送事件通知。
而相较之下,AJAX是基于多次HTTP请求来实现数据的通讯的,一般是从客户端向服务器请求数据,这种方式有助于节省带宽,连接合理时很有效,但通常情况下也会引入额外的时延。
2. 连接维持长连接
SSE建立一次连接后,服务端可以一直发送多个事件消息,而不需要每次重新建立连接,从而节省了建立连接的时间开销以及其带来的带宽占用。相较之下,AJAX、WebSocket的通讯方式并没有批量发送请求、批量响应数据的能力,还需要新建连接才能继续通讯。
3. 信息格式
SSE解决了WebSocket通信的服务器端代码和客户端代码不好编写的问题,任何一个支持HTTP的Web服务器都能支持SSE,并且不需要额外的代码和工作的库。
WebSocket对于处理大规模实时数据的优化是非常好的。但WebSocket对于开发者和终端设备的收发能力限制较大,不适用于灵活的数据应用场景。 SSE是与WEB CORS方案无关,能够解决新版本浏览器跨域请求的问题。这也是SSE技术实际应用中被广泛使用的主要原因。
4. 处理复杂性
AJAX通讯模式必然涉及到繁琐的XMLHttpRequest对象的创建、请求数据格式的组织、返回数据解析以及事件委托的实现。而WebSocket通讯模式在低延迟的通讯中可能需要通过协议层手段来保证数据可靠性。这些功能的实现和处理方式带来了WebSocket和AJAX技术实际应用的复杂性。
Server-Sent Events在不管是服务端编写方面,还是客户端编写方面都比其它技术要简便许多。服务端只需要为事件类型和消息内容丰富的业务逻辑的实现即可,客户端则只需要监听对应事件类型的回调函数的定义就可以轻松实现服务器端消息的获取和处理。
使用场景
Server-Sent Events非常适用于对实时数据展示非常关键的应用,比如:实时行情、监控数据等。相对于WebSocket而言,Server-Sent Events更加简单,而且能够更好地保证数据的传输。而相较于AJAX,Server-Sent Events相对更加实时,在获取实时数据的应用场景下优势明显。
在实践中,SSE还可以结合已有的技术和框架一起使用 ,比如,结合Node.js和Express框架使用,可以很方便地创建SSE服务器。服务端使用res.write()来向客户端发送事件流,客户端使用标准的EventSource()对象来订阅服务端发送的事件流,这些代码非常容易写,也易于理解。
示例代码
服务端代码
-- -------------------- ---- ------- ----- ------- - ------------------ ----- --- - --------- --------------- ------------- ---- - ------------------ - --------------- -------------------- ---------------- ----------- ------------------------------ --- -- ---------------------- - ---------------------------- - - --- ------ - -------- -- ------ -- --------------------------- ------------------- -- ------------ --展开代码
客户端代码
-- -------------------- ---- ------- --------- ----- ------ ------ ------------------ ------ ---------- ------- ------ --------------- ------ ------- ---- ----- ------------ ------ ------- -------- --- ------ - --- ----------------------------------------- ------------------------------- --------------- - ---------------------------------------------------------------- --- --------- ------- -------展开代码
此代码效果演示,每隔1秒就会向客户端发送一条当前时间。
结论
总结一下,对于实时性比较高的数据补充,选择使用Server-Sent Events是一个不错的选择。SSE优势在于不需要客户端创建多个HTTP连接,相较之下,WebSocket要创建双向连接,同时创建多个连接的时候,服务端也需要保留多个WebSocket连接。但是,对于高实时性的实时通讯,WebSocket仍然是更好的选择。
从数据的传输方式来看,掌握Server-Sent Events通过服务器端向客户端发送事件,将会对实现实时web应用和实时地图特别有用。
在实际应用中,最佳的解决方案显然是将Ajax、Server-Sent Events和WebSocket技术相结合使用。根据数据实时性的需要,可以进行切换使用,从而保证了应用的高可用性,更加实用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/646b2df0968c7c53b0a97c78