浅浅分享一下SSE(Server-Sent Events,服务器发送事件)

712 阅读2分钟

前段时间用到SSE使用了EventSource,浅浅分享一下;

SSE(Server-Sent Events,服务器发送事件)可以实现服务器向客户端推送实时数据。SSE是一种基于HTTP的通信协议,与WebSocket不同,SSE只在单向通信模式下工作,即只能由服务器向客户端发送数据。使用SSE可以在前端接收来自服务器的实时数据,通常用于实现实时通信、实时更新等功能。 EventSource 接口是 web 内容与服务器发送事件通信的接口。

一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close() 关闭。

一旦连接开启,来自服务端传入的消息会以事件的形式分发至你代码中。如果接收消息中有一个 event 字段,触发的事件与 event 字段的值相同。如果不存在 event 字段,则将触发通用的 message 事件。

与 WebSocket 不同的是,服务器发送事件是单向的。数据消息只能从服务端到发送到客户端(如用户的浏览器)。这使其成为不需要从客户端往服务器发送消息的情况下的最佳选择。例如,对于处理如社交媒体状态更新、消息来源(news feed)或将数据传递到客户端存储机制(如 IndexedDB 或 web 存储)之类的,EventSource 无疑是一个有效方案。

以下是在我在使用SSE的一些基本步骤:

  1. 创建一个EventSource对象,并指定服务器的URL: var source = new EventSource("server.url");

由于EventSource建立的连接也属于http请求, 所以后端接口如果需要鉴权,在请求体里面加上参数,可以安装依赖'event-source-polyfill', 直接yarn add event-source-polyfill 即可使用; var eventSource = new EventSourcePolyfill( url, { headers: { 'Authorization': token, } } )

  1. 监听message事件
<template>
   <div id="sseData" ref="sseData"></div>
</template>

<script>
import { EventSourcePolyfill } from 'event-source-polyfill';
export default {
    data(){
      return {
          eventSource: null,
      }  
    },
    methods: {
        onConnection() {
            this.eventSource = new EventSourcePolyfill(
                `/dispose/sse/createConnect/?pictures=${keys}`, {
                  headers: {
                    'Authorization': this.accessToken || GoodStorage.get('AccessToken'),
                    'DeptCode': this.depCode || GoodStorage.get('DeptCode')
                  }
                }
              )
            this.eventSource.addEventListener('message', e => {
            // 开始标识
            if (e.lastEventId == '200') {
              const event = JSON.parse(e.data)
              this.transformLoading = false
              if (event.data && event.data !== 'end标识') {
                this.$refs.sseData.innerHTML += event.data
              } else if (event.data === 'end标识') {
                this.eventSource?.close()
                this.eventSource = null
              }
            }
           })
           this.eventSource.addEventListener('open', e => {
            console.log('open', e);
          })
          this.eventSource.addEventListener('error', e => {
            if (e.error) {
              this.eventSource?.close()
              this.eventSource = null
            }
          })
        }
    }
}
</scrupt>

大概使用过程就是如此, 后端返回的数据结构可能不同, 需要做不同的处理。需要注意的是,SSE仅支持单向通信,即只能由服务器向客户端发送数据。如果需要实现双向通信,可以考虑使用WebSocket或其他协议。