利用SSE与Mercure实现SPA异步数据更新
前端应用需要持续的数据更新以反映后端变化。标准API调用仅能捕获响应时刻的状态,但后端会持续处理事件:如账户充值、内容审核、客服回复等。为此,我们采用基于SSE的推送机制,并与现有OpenAPI规范集成。
该系统结合了拉取方式(定期请求)与推送方式(实时通知)。SSE通过HTTP/2提供单向事件流,相比轮询能显著降低负载。
异步通知的应用场景
异步通知在业务流程中至关重要:
- 余额充值:显示当前状态以便即时购买。
- 内容审核:审核后更新状态。
- 客服回复:即时通知新工单。
在典型场景中,用户(如广告主或承包商)会跟踪请求计数器:需要操作的数量、未读评论、投放检查等。这些数据可通过API端点/rest/User/info(操作ID:getInfo)获取。
/rest/User/info:
get:
tags:
- User
summary: 返回当前用户信息
operationId: getInfo
responses:
200:
description: 当前用户信息
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int32
minimum: 0
locale:
type: string
enum: [ru, en]
login:
type: string
minimum: 3
maximum: 320
seoCounters:
$ref: '#/components/schemas/SeoCounters'
SeoCounters模式定义了结构:
SeoCounters:
type: object
properties:
nofRequests:
type: integer
format: int32
minimum: 0
nofLinksStatusNeedApprove:
type: integer
format: int32
minimum: 0
nofLinksWithUnreadComments:
type: integer
format: int32
minimum: 0
nofChanges:
type: integer
format: int32
minimum: 0
nofPlacementCheck:
type: integer
format: int32
minimum: 0
集成CDC与数据平台
user_counters表中的变更通过CDC(变更数据捕获)进行跟踪。修改流被发送到数据平台——一个企业级ETL系统。从那里,事件通过SSE枢纽推送到用户界面。
架构采用六边形模型:OpenAPI规范自动生成REST适配器和TypeScript类型。对于前端,类型如下所示:
/* 由orval生成 */
export interface SeoCounters {
nofRequests?: number;
nofLinksStatusNeedApprove?: number;
nofLinksWithUnreadComments?: number;
nofChanges?: number;
nofPlacementCheck?: number;
}
export type GetInfo200 = {
id: number;
locale: 'ru' | 'en';
login: string;
seoCounters?: SeoCounters;
};
这些类型被复用于处理SSE事件,确保类型安全。
在应用中实现SSE
SSE(服务器发送事件)是服务器推送的标准,由浏览器支持。EventSource连接到端点:
const evtSource = new EventSource('/sse-endpoint', {
withCredentials: true,
});
evtSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// 使用类型化数据更新存储
updateSeoCounters(data.seoCounters);
};
对于授权、主题和扩展,我们使用Mercure——一个基于SSE的开源枢纽。该枢纽通过REST接受带有JWT的发布,并向订阅者广播。
发布示例:
curl -d 'topic=https://example.com/books/1' \
-d 'data={"foo": "updated value"}' \
-H 'Authorization: Bearer <JWT>' \
-X POST https://hub/.well-known/mercure
JWT定义了主题的发布/订阅权限。Mercure作为容器部署,带有外部数据库,并与CDC流集成。
该方法的优势
- 模式复用:OpenAPI结构在拉取和推送中复用,无需重复。
- 实时性:变更即时反映,无需轮询。
- 可扩展性:Mercure枢纽分发负载。
监控的关键计数器列表:
nofRequests—— 操作请求。nofLinksStatusNeedApprove—— 待批准链接。nofLinksWithUnreadComments—— 未读评论。nofPlacementCheck—— 投放检查。
关键要点
- SSE与Mercure提供类型化推送通知,无需WebSocket开销。
- CDC实时捕获数据库变更以用于ETL流程。
- 从OpenAPI自动生成TypeScript类型确保数据一致性。
- 该方法适用于高负载系统,支持数千用户。
- Mercure中的JWT管理通知主题的访问权限。
— Editorial Team
暂无评论。