NestJS 中使用服务器端事件进行批量操作的轻松通知

Temp mail SuperHeros
NestJS 中使用服务器端事件进行批量操作的轻松通知
NestJS 中使用服务器端事件进行批量操作的轻松通知

简化批量插入操作的通知传送

想象一下,您正在管理一个系统,其中数百名员工根据部门、级别或经验等各种标准分配了凭证。在不造成系统瓶颈的情况下有效地通知每位员工是一项艰巨的任务。 🔔 当您的目标是避免套接字或轮询机制的复杂性时,这个挑战变得更加艰巨。

在这种情况下,服务器端事件 (SSE) 成为一种强大而简单的解决方案。通过在 NestJS 应用程序中利用 SSE,您可以建立实时通信渠道,根据动态标准通知特定的员工组。例如,当优惠券分配给销售部门时,只有这些员工应该收到通知,以确保准确且有意义的更新。

通过本文,我们将深入研究一个实际示例,演示如何使用 NestJS 将 SSE 集成到批量插入过程中。我们将逐步介绍整个生命周期,从触发后端事件到监听前端更新,同时保持无缝性能。 💼

无论您是在开发人力资源工具还是财务应用程序,了解此工作流程都将使您能够实时提供个性化通知。让我们揭开 SSE 的简单性以及它如何提升应用程序的用户体验。

命令 使用示例
@Sse 用于定义服务器端事件 (SSE) 端点的 NestJS 装饰器。例如, @Sse('凭单员工') 设置端点以将实时更新传输到客户端。
fromEvent RxJS 中的函数,用于转换由 事件发射器 进入可观察的流。 例如, fromEvent(this.eventEmitter, '添加后的优惠券') 监听特定事件。
Observable RxJS 的核心概念,用于管理异步数据流。 它对于处理 NestJS 中的服务器端事件至关重要,例如 可观察的<MessageEvent>
@InjectQueue 一个注入队列实例的 NestJS 装饰器,对于使用 Bull 等库管理作业处理非常有用。 例如, @InjectQueue('allotVoucher') 提供对名为“allotVoucher”的队列的访问。
WorkerHost BullMQ 的基类,允许在 NestJS 中定义自定义作业处理器。 例如, 分配优惠券消费者 类扩展 工作主机 来处理特定的工作。
@OnWorkerEvent 用于监听队列作业的特定生命周期事件的装饰器。 例如, @OnWorkerEvent('完成') 处理作业的“已完成”事件。
createMany Prisma 命令用于一次将多条记录插入数据库。 例如, prisma.employeeVoucher.createMany 在一次操作中添加所有员工的凭证。
EventSource 用于从后端接收服务器发送的事件 (SSE) 的 JavaScript API。 例如, 新的 EventSource('http://localhost/vouchered-employee') 建立流数据连接。
add Bull 队列中的一种方法,用于将新作业添加到队列中。 例如, allotVoucherQueue.add('分配凭证', jobData) 安排要处理的作业。
@OnEvent 一个 NestJS 装饰器,用于侦听应用程序内发出的特定事件。 例如, @OnEvent('分配后优惠券') 发出此事件时触发方法。

通过服务器端事件和队列进行高效通知

提供的脚本演示了一个系统,在将凭证记录批量插入数据库后,实时通知会发送给员工。该过程开始于 分配凭证控制器,它公开用于创建凭证分配任务的端点。当一个任务被创建时,它会发出一个名为的事件 后分配凭证。该事件对于触发后续步骤至关重要,确保系统是事件驱动的、模块化的。这种设计可以清晰地分离关注点,使系统更具可维护性和可扩展性。 🎯

在服务层, 分配优惠券服务 使用 BullMQ 处理排队任务的逻辑。收到后 后分配凭证 事件,它将一个作业添加到名为的队列中 分配凭证。该队列允许异步处理,确保系统即使在处理大型数据集时也能保持响应。例如,如果您将凭证分配给销售部门的 200 名员工,队列将确保该操作不会阻塞其他请求。队列的配置包括以下选项 完成时删除 作业完成后保持 Redis 清洁。

队列作业由 分配优惠券消费者 班级。这里实现了识别相关员工并将凭证记录插入数据库的逻辑。 Prisma 命令 创建许多 用于批量插入记录到 员工券 表,针对性能进行了优化。数据库操作完成后,会发出另一个事件来通知订阅者。此事件确保仅在成功处理批量插入后才通知员工,从而提高了通知系统的可靠性。 🌟

在前端,React 组件通过一个监听器监听服务器发送的事件 事件源。当员工收到通知时,他们的详细信息会在 UI 中动态更新,无需刷新页面。这种方法提供了无缝的用户体验,类似于现代网络应用程序中的实时更新,例如实时体育赛事比分或社交媒体通知。例如,人力资源部门的员工不会看到针对销售的更新,因为后端根据分配标准精确过滤事件。这种特殊性增强了性能和相关性,创建了一个以用户为中心的系统。 🖥️

使用 NestJS 中的服务器端事件 (SSE) 批量发送通知

该解决方案演示了使用 NestJS 与 Prisma 和服务器端事件 (SSE) 进行批量操作的后端方法。它包括事件驱动的架构和排队系统。

// Backend: AllocateVoucherController
import { Controller, Post, Body, Sse, OnEvent } from '@nestjs/common';
import { AllocateVoucherService } from './allocate-voucher.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Observable } from 'rxjs';
import { map, fromEvent } from 'rxjs';
@Controller('allocate-voucher')
export class AllocateVoucherController {
  constructor(
    private readonly allocateVoucherService: AllocateVoucherService,
    private readonly eventEmitter: EventEmitter2
  ) {}
  @Post()
  async create(@Body() createDto: any) {
    const result = await this.allocateVoucherService.create(createDto);
    return result;
  }
  @Sse('vouchered-employee')
  updatedEmployeeEvent(): Observable<MessageEvent> {
    return fromEvent(this.eventEmitter, 'after-added-voucher').pipe(
      map((data) => new MessageEvent('after-added-voucher', { data })),
    );
  }
}

使用 NestJS 和 React 进行批量插入的实时更新

此前端示例使用 React 来侦听服务器端事件并在收到数据时动态更新 UI。它确保员工在批量插入后实时收到通知。

// Frontend: React Component for SSE
import React, { useEffect, useState } from 'react';
const EmployeeUpdates = () => {
  const [employees, setEmployees] = useState([]);
  useEffect(() => {
    const eventSource = new EventSource('http://localhost:3000/allocate-voucher/vouchered-employee');
    eventSource.onmessage = (event) => {
      const newEmployee = JSON.parse(event.data);
      setEmployees((prev) => [...prev, newEmployee]);
    };
    return () => eventSource.close();
  }, []);
  return (
    <table>
      <thead>
        <tr><th>Name</th><th>Voucher</th></tr>
      </thead>
      <tbody>
        {employees.map((emp) => (
          <tr key={emp.id}><td>{emp.name}</td><td>{emp.voucher}</td></tr>
        ))}
      </tbody>
    </table>
  );
};
export default EmployeeUpdates;

批量插入操作的单元测试通知

此 Jest 测试确保事件发射和通知机制在 NestJS 中服务器端事件的后端正常工作。

// Jest Test: AllocateVoucherService
import { Test, TestingModule } from '@nestjs/testing';
import { AllocateVoucherService } from './allocate-voucher.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
describe('AllocateVoucherService', () => {
  let service: AllocateVoucherService;
  let eventEmitter: EventEmitter2;
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [AllocateVoucherService, EventEmitter2],
    }).compile();
    service = module.get(AllocateVoucherService);
    eventEmitter = module.get(EventEmitter2);
  });
  it('should emit after-allocate-voucher event', async () => {
    jest.spyOn(eventEmitter, 'emit');
    const result = await service.create({ someData: 'test' });
    expect(eventEmitter.emit).toHaveBeenCalledWith('after-allocate-voucher', result);
  });
});

使用 NestJS 中的 SSE 增强实时系统

虽然我们已经探索了服务器端事件 (SSE) 的实现来通知员工有关凭证分配的信息,但 SSE 在实时系统中还有更广泛的用例。 SSE 在客户端需要保持服务器数据更新而无需不断轮询的场景中表现出色。例如,考虑一个在闪购期间跟踪实时库存更新的在线零售平台。使用 SSE,您可以有效地将更新推送到所有连接的客户端,确保他们查看最新的库存水平,而无需增加不必要的服务器负载。这种方法确保了可扩展性,同时保持无缝的用户体验。 🛒

结合 BullMQ 等高级排队系统,就像我们对 分配凭证 队列,增加了批量数据处理任务的鲁棒性。该队列确保即使发生服务器重新启动,挂起的任务也保持不变,并且处理会恢复。此外,可以配置重试机制,确保自动重试失败的作业(例如,由于临时数据库停机)。例如,如果对跨部门 300 名员工的分配遇到临时错误,队列的弹性可确保没有未处理的记录,从而提高系统的可靠性。

除了实时通知之外,SSE 还可以补充电子邮件服务来完成需要详细摘要的任务。所有凭证通知通过 SSE 发送后,后端可以异步生成报告并向经理发送合并电子邮件。这种多渠道通信确保了即时通知和全面的后续行动,满足了广泛的用户偏好。这种集成增强了系统的灵活性,创造了全面的用户体验。 📧

关于 NestJS 中的 SSE 的常见问题

  1. 通过 WebSocket 使用服务器端事件有哪些好处?
  2. SSE 实现起来更简单,并且使用 HTTP,因此对防火墙友好。与 WebSocket 不同,它只需要单个单向连接,这对于实时更新非常有效。
  3. 我可以使用吗 @Sse 控制器中有多个端点?
  4. 是的,您可以定义多个 @Sse 同一控制器中的端点可根据特定需求向客户端提供不同的数据流。
  5. 如何处理队列处理过程中的错误?
  6. 使用 BullMQ,您可以定义重试选项并使用事件侦听器,例如 @OnWorkerEvent('failed') 记录错误并在必要时重新处理作业。
  7. Prisma 有吗 createMany 方法支持事务回滚吗?
  8. 是的,棱镜的 createMany 可以封装在交易中。如果事务中的任何操作失败,则回滚所有操作以保持一致性。
  9. 如果客户端在 SSE 流期间断开连接会发生什么?
  10. 一旦检测到断开连接,服务器就会停止发送更新。您可以使用以下方法在客户端上实现重新连接逻辑 EventSource API。
  11. SSE可以用于双向通信吗?
  12. 不,SSE 是单向的(服务器到客户端)。对于双向通信,请使用 WebSocket 或 HTTP2 流。
  13. 如何保护 NestJS 中的 SSE 端点?
  14. 使用警卫或中间件,例如 @UseGuards,对您的 SSE 端点实施身份验证和授权。
  15. SSE 可以与非浏览器客户端一起使用吗?
  16. 是的,任何支持 HTTP 和事件流的客户端(例如 Node.js、cURL)都可以使用 SSE 流。
  17. 可以连接到 SSE 端点的最大客户端数量是多少?
  18. 这取决于您的服务器的配置和资源限制。负载平衡和集群可以帮助扩展以支持更多客户端。
  19. 是否可以通过 SSE 发送 JSON 数据?
  20. 是的,您可以将对象序列化为 JSON 字符串并使用 new MessageEvent 在 NestJS 中。

NestJS 中有效的实时通知

使用实现实时系统 上证所 NestJS 简化了服务器和客户端之间的通信。与持续轮询相比,此方法减少了服务器负载,并实现了通知的精确定位。例如,HR 工具可以向销售部门的 200 名员工通知新优惠券,而不会干扰其他人。 🎯

借助 BullMQ 和 Prisma 等工具,此设置可确保异步任务处理和高效的数据库操作。基于事件的架构的灵活性使其成为满足各种实时要求的可扩展解决方案,从而增强用户参与度和系统可靠性。

来源和参考文献
  1. 详细文档 NestJS框架 用于构建可扩展的服务器端应用程序。
  2. 使用指南 BullMQ 用于 Node.js 应用程序中强大的作业队列管理。
  3. 官方的 Prisma 文档 用于数据库操作和 ORM 使用。
  4. 见解 服务器发送的事件 (SSE) 用于实时客户端-服务器通信。
  5. 实用的前端实现示例 ReactJS 文档 用于构建交互式用户界面。