技术分享
SSE(Server-Sent Events)原理分析
00 分钟
2023-6-15
2023-9-15
type
status
date
slug
summary
tags
category
icon
password
Server-Sent Events(SSE,服务器推送事件)是一种基于HTTP的服务器推送技术,可以让服务器实时向客户端推送数据。相比于传统的Ajax轮询和WebSockets,SSE具有轻量级、简单易用、易于实现和兼容性好等优点,适用于一些实时通知、实时数据展示等场景。
SSE使用了HTTP长连接,即服务器保持连接处于打开状态,不断向客户端发送数据。客户端使用EventSource API来接收服务器发送的数据,并在接收到数据时进行处理。
 

一、实现原理

下面是一个简单的SSE实现的示例:
服务端代码(使用Node.js):
客户端代码:
上述代码中,服务端使用Node.js创建一个HTTP服务器,设置响应头为text/event-stream,然后向客户端发送数据。客户端使用JavaScript创建一个EventSource对象,指定服务端URL,然后处理从服务端发送过来的数据。
需要注意的是,SSE使用的是HTTP长连接,因此需要注意服务器端和客户端的超时设置,以避免连接断开。
 

二、鉴权处理

如果要在SSE中加上鉴权处理,可以在服务端对每一个客户端连接进行身份验证,只有经过验证的连接才能收到数据,下面是一个示例代码:
服务端代码(使用Node.js):
 

三、结合框架实现

Koa 框架

如果要在Koa框架中实现SSE,可以使用koa-sse中间件来处理SSE请求和响应。
我们使用koa-sse中间件处理SSE请求和响应。在中间件中,我们首先进行身份验证,然后根据验证结果设置响应头为text/event-stream,并向客户端发送数据。
使用koa-sse中间件的好处是它提供了方便的API来发送数据,我们只需要调用ctx.sse.send()方法即可向客户端发送数据。另外,中间件还会自动处理连接断开等情况,确保连接不会因为异常情况而断开。
 

Nest框架

在 Nest 框架中实现 SSE 可以借助 nestjs-sse 这个官方提供的插件,它为 SSE 的实现提供了一些基础功能,例如自动处理连接维护、发送消息等。
我们创建了一个 SSE 控制器,在控制器的 streamData方法中,我们首先通过 AuthService验证用户,如果验证失败,可以通过 event.close()方法关闭 SSE 连接,否则我们可以使event.send() 方法发送 SSE 数据。
 
值得注意的是,在上述代码中我们使用了 @MessageEvent() 装饰器将 event 对象注入到控制器方法中,我们可以通过该对象访问 SSE 连接的相关信息。
另外,我们还需要在 NestJS 的模块中引入 SseModule,例如:
引入了 SseModule并将其加入到模块的 imports中,这样 SSE 控制器就可以使用 @Sse()装饰器了。我们还将 AuthService注册为模块的 providers,这样在 SSE 控制器中就可以使用该服务进行用户验证了。