Łatwe powiadomienia w NestJS przy użyciu zdarzeń po stronie serwera do operacji masowych

Temp mail SuperHeros
Łatwe powiadomienia w NestJS przy użyciu zdarzeń po stronie serwera do operacji masowych
Łatwe powiadomienia w NestJS przy użyciu zdarzeń po stronie serwera do operacji masowych

Usprawnione dostarczanie powiadomień w przypadku operacji wstawiania zbiorczego

Wyobraź sobie, że zarządzasz systemem, w którym setki pracowników otrzymują kupony na podstawie różnych kryteriów, takich jak dział, stopień lub doświadczenie. Sprawne powiadomienie każdego pracownika bez powodowania wąskich gardeł w systemie to kolosalne zadanie. 🔔 To wyzwanie staje się jeszcze bardziej zniechęcające, gdy chcesz uniknąć złożoności gniazd lub mechanizmów odpytywania.

W takich scenariuszach zdarzenia po stronie serwera (SSE) okazują się potężnym, a jednocześnie prostym rozwiązaniem. Wykorzystując SSE w aplikacji NestJS, możesz ustanowić kanał komunikacji w czasie rzeczywistym, aby powiadamiać określone grupy pracowników w oparciu o dynamiczne kryteria. Przykładowo, w przypadku przydzielenia voucherów do działu sprzedaży, tylko ci pracownicy powinni otrzymywać powiadomienia, zapewniając precyzyjne i istotne aktualizacje.

W tym artykule zagłębimy się w praktyczny przykład pokazujący, jak zintegrować SSE z procesem wstawiania zbiorczego za pomocą NestJS. Przejdziemy przez cykl życia, od wyzwalania zdarzeń w backendie po nasłuchiwanie aktualizacji w frontendzie, a wszystko to przy zachowaniu płynnej wydajności. 💼

Niezależnie od tego, czy tworzysz narzędzie HR, czy aplikację finansową, zrozumienie tego przepływu pracy umożliwi Ci dostarczanie spersonalizowanych powiadomień w czasie rzeczywistym. Odkryjmy prostotę SSE i sposób, w jaki może ona podnieść komfort korzystania z aplikacji.

Rozkaz Przykład użycia
@Sse Dekorator NestJS używany do definiowania punktu końcowego zdarzeń po stronie serwera (SSE). Na przykład, @Sse('pracownik z kuponem') konfiguruje punkt końcowy do przesyłania strumieniowego aktualizacji w czasie rzeczywistym do klienta.
fromEvent Funkcja z RxJS, która konwertuje zdarzenie emitowane przez an Emiter zdarzeń w obserwowalny strumień. Na przykład, fromEvent(this.eventEmitter, 'kupon-po-dodaniu') nasłuchuje konkretnego zdarzenia.
Observable Podstawowa koncepcja RxJS używana do zarządzania asynchronicznymi strumieniami danych. Jest to niezbędne do obsługi zdarzeń po stronie serwera w NestJS, takich jak Zauważalny<MessageEvent>.
@InjectQueue Dekorator NestJS, który wstawia instancję kolejki, przydatny do zarządzania przetwarzaniem zadań za pomocą bibliotek takich jak Bull. Na przykład, @InjectQueue('allotVoucher') zapewnia dostęp do kolejki o nazwie „allotVoucher”.
WorkerHost Klasa bazowa z BullMQ, która umożliwia definiowanie niestandardowych procesorów zadań w NestJS. Na przykład Przydziel VoucherKonsument klasa się poszerza PracownikHost do obsługi określonych zadań.
@OnWorkerEvent Dekorator używany do nasłuchiwania określonych zdarzeń cyklu życia zadania w kolejce. Na przykład, @OnWorkerEvent('ukończone') obsługuje zdarzenie „zakończenia” zadania.
createMany Polecenie Prisma używane do jednoczesnego wstawiania wielu rekordów do bazy danych. Na przykład, prisma.employee Voucher.createMany dodaje bony wszystkich pracowników w jednej operacji.
EventSource Interfejs API JavaScript do odbierania zdarzeń wysyłanych przez serwer (SSE) z backendu. Na przykład, nowe źródło zdarzenia('http://localhost/vouchered-employee') nawiązuje połączenie w celu przesyłania strumieniowego danych.
add Metoda z kolejek Bull służąca do dodawania nowego zadania do kolejki. Na przykład, allotVoucherQueue.add('allot-voucher', jobData) planuje zadanie do przetworzenia.
@OnEvent Dekorator NestJS, który nasłuchuje określonych zdarzeń emitowanych w aplikacji. Na przykład, @OnEvent('kupon-po przydzieleniu') wyzwala metodę po wyemitowaniu tego zdarzenia.

Wydajne powiadomienia ze zdarzeniami i kolejkami po stronie serwera

Dostarczone skrypty ilustrują system, w którym powiadomienia w czasie rzeczywistym wysyłane są do pracowników po zbiorczym wprowadzeniu rekordów voucherów do bazy danych. Proces rozpoczyna się w Przydziel kontroler Voucher, który udostępnia punkt końcowy do tworzenia zadań alokacji kuponów. Kiedy zadanie jest tworzone, emituje zdarzenie o nazwie kupon po przyznaniu. To zdarzenie jest niezbędne do uruchomienia kolejnych kroków, zapewniając, że system jest sterowany zdarzeniami i modułowy. Taka konstrukcja pozwala na wyraźne oddzielenie problemów, dzięki czemu system jest łatwiejszy w utrzymaniu i skalowalny. 🎯

W warstwie usług Przydziel usługę Voucher obsługuje logikę kolejkowania zadań przy użyciu BullMQ. Po otrzymaniu kupon po przydzieleniu zdarzenie, dodaje zadanie do kolejki o nazwie kupon-przydział. Ta kolejka umożliwia przetwarzanie asynchroniczne, zapewniając responsywność systemu nawet podczas przetwarzania dużych zbiorów danych. Przykładowo, jeśli przydzielisz vouchery 200 pracownikom Działu Sprzedaży, kolejka gwarantuje, że operacja nie zablokuje innych żądań. Konfiguracja kolejki obejmuje opcje takie jak usuńOnComplete aby utrzymać Redis w czystości po zakończeniu pracy.

Zadania kolejki są przetwarzane przez Przydziel VoucherKonsument klasa. W tym miejscu zaimplementowana jest logika identyfikacji odpowiednich pracowników i umieszczania rekordów bonów w bazie danych. Polecenie Prisma utwórzWiele służy do zbiorczego wstawiania rekordów do pliku Voucher pracowniczy tabeli zoptymalizowanej pod kątem wydajności. Po zakończeniu operacji na bazie danych emitowane jest kolejne zdarzenie powiadamiające subskrybentów. To zdarzenie gwarantuje, że pracownicy zostaną powiadomieni dopiero po pomyślnym przetworzeniu zbiorczego wstawiania, co zwiększa niezawodność systemu powiadomień. 🌟

Na froncie komponent React nasłuchuje zdarzeń wysyłanych przez serwer poprzez: Źródło zdarzenia. Po powiadomieniu pracowników ich dane są dynamicznie aktualizowane w interfejsie użytkownika bez konieczności odświeżania strony. Takie podejście zapewnia płynną obsługę użytkownika, podobną do aktualizacji w czasie rzeczywistym, które można zobaczyć w nowoczesnych aplikacjach internetowych, takich jak wyniki sportowe na żywo lub powiadomienia w mediach społecznościowych. Przykładowo pracownicy działu HR nie zobaczą aktualizacji przeznaczonych dla Sprzedaży, gdyż backend precyzyjnie filtruje zdarzenia na podstawie kryteriów alokacji. Ta specyfika zwiększa zarówno wydajność, jak i przydatność, tworząc system zorientowany na użytkownika. 🖥️

Zbiorcze wysyłanie powiadomień za pomocą zdarzeń po stronie serwera (SSE) w NestJS

To rozwiązanie demonstruje podejście backendowe do używania NestJS z Prisma i zdarzeniami po stronie serwera (SSE) do operacji masowych. Zawiera architekturę sterowaną zdarzeniami i system kolejkowania.

// 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 })),
    );
  }
}

Aktualizacje w czasie rzeczywistym dla wstawek zbiorczych za pomocą NestJS i React

W tym przykładzie frontendu zastosowano React do nasłuchiwania zdarzeń po stronie serwera i dynamicznego aktualizowania interfejsu użytkownika w miarę odbierania danych. Zapewnia, że ​​pracownicy zostaną powiadomieni w czasie rzeczywistym po zbiorczym wstawieniu.

// 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;

Powiadomienia o testowaniu jednostkowym dla operacji wstawiania zbiorczego

Ten test Jest zapewnia, że ​​mechanizm emisji i powiadamiania o zdarzeniach działa poprawnie w backendie zdarzeń po stronie serwera w 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);
  });
});

Udoskonalanie systemów czasu rzeczywistego za pomocą SSE w NestJS

Chociaż badaliśmy wdrożenie zdarzeń po stronie serwera (SSE) do powiadamiania pracowników o przydzielaniu kuponów, istnieje szerszy przypadek użycia SSE w systemach czasu rzeczywistego. SSE sprawdza się w scenariuszach, w których klienci muszą być na bieżąco z danymi serwera bez ciągłego odpytywania. Pomyśl na przykład o internetowej platformie sprzedaży detalicznej śledzącej na bieżąco aktualizacje zapasów podczas wyprzedaży błyskawicznej. Korzystając z SSE, możesz efektywnie przesyłać aktualizacje do wszystkich podłączonych klientów, upewniając się, że przeglądają najnowsze stany magazynowe bez niepotrzebnego obciążenia serwera. Takie podejście zapewnia skalowalność, a jednocześnie zapewnia bezproblemową obsługę użytkownika. 🛒

Włączając zaawansowane systemy kolejkowania, takie jak BullMQ, tak jak to zrobiliśmy w przypadku kupon-przydział kolejki, zwiększa niezawodność zadań masowego przetwarzania danych. Kolejka gwarantuje, że nawet w przypadku ponownego uruchomienia serwera oczekujące zadania pozostaną nienaruszone, a przetwarzanie zostanie wznowione. Dodatkowo można skonfigurować mechanizmy ponawiania, dzięki którym zadania zakończone niepowodzeniem (np. z powodu tymczasowego przestoju bazy danych) będą automatycznie ponawiane. Na przykład, jeśli przydział do 300 pracowników w różnych działach napotka tymczasowy błąd, odporność kolejki gwarantuje, że żadne rekordy nie pozostaną nieprzetworzone, co zwiększa niezawodność systemu.

Oprócz powiadomień w czasie rzeczywistym SSE może również uzupełniać usługi e-mailowe w przypadku zadań wymagających szczegółowych podsumowań. Po wysłaniu wszystkich powiadomień o kuponach za pośrednictwem SSE backend może asynchronicznie wygenerować raport i wysłać skonsolidowaną wiadomość e-mail do menedżerów. Ta wielokanałowa komunikacja zapewnia zarówno natychmiastowe powiadomienia, jak i kompleksowe działania następcze, uwzględniające szeroki zakres preferencji użytkowników. Taka integracja zwiększa elastyczność systemu, tworząc wszechstronne doświadczenie użytkownika. 📧

Często zadawane pytania dotyczące SSE w NestJS

  1. Jakie są zalety korzystania ze zdarzeń po stronie serwera za pośrednictwem gniazd WebSocket?
  2. SSE jest prostsze we wdrożeniu i wykorzystuje protokół HTTP, dzięki czemu jest przyjazne dla zapory sieciowej. W przeciwieństwie do WebSockets wymaga tylko jednego połączenia jednokierunkowego, które jest wydajne w przypadku aktualizacji w czasie rzeczywistym.
  3. Czy mogę użyć @Sse z wieloma punktami końcowymi w kontrolerze?
  4. Tak, możesz zdefiniować wiele @Sse punkty końcowe w tym samym kontrolerze, aby udostępniać klientom różne strumienie danych w zależności od konkretnych potrzeb.
  5. Jak radzić sobie z błędami podczas przetwarzania kolejki?
  6. Dzięki BullMQ możesz zdefiniować opcje ponawiania prób i używać detektorów zdarzeń, takich jak @OnWorkerEvent('failed') rejestrować błędy i w razie potrzeby ponownie przetwarzać zadania.
  7. Czy Prisma createMany metoda obsługuje wycofywanie transakcji?
  8. Tak, Prismy createMany można zawrzeć w transakcji. Jeśli jakakolwiek operacja w transakcji zakończy się niepowodzeniem, wszystkie operacje zostaną wycofywane w celu zapewnienia spójności.
  9. Co się stanie, jeśli klient rozłączy się podczas strumienia SSE?
  10. Serwer przestaje wysyłać aktualizacje po wykryciu rozłączenia. Możesz zaimplementować logikę ponownego łączenia na kliencie za pomocą EventSource API.
  11. Czy SSE można używać do komunikacji dwukierunkowej?
  12. Nie, SSE jest jednokierunkowe (serwer-klient). Do komunikacji dwukierunkowej użyj strumieni WebSockets lub HTTP2.
  13. Jak zabezpieczyć punkty końcowe SSE w NestJS?
  14. Użyj osłon lub oprogramowania pośredniego, np @UseGuards, aby wymusić uwierzytelnianie i autoryzację dla punktów końcowych SSE.
  15. Czy SSE może współpracować z klientami innymi niż przeglądarka?
  16. Tak, każdy klient obsługujący protokół HTTP i strumieniowanie zdarzeń (np. Node.js, cURL) może korzystać ze strumieni SSE.
  17. Jaka jest maksymalna liczba klientów, którzy mogą połączyć się z punktem końcowym SSE?
  18. Zależy to od konfiguracji serwera i limitów zasobów. Równoważenie obciążenia i klastrowanie mogą pomóc w skalowaniu w celu obsługi większej liczby klientów.
  19. Czy można wysyłać dane JSON przez SSE?
  20. Tak, możesz serializować obiekty do ciągów JSON i wysyłać je za pomocą new MessageEvent w NestJS.

Skuteczne powiadomienia w czasie rzeczywistym w NestJS

Wdrażanie systemów czasu rzeczywistego z wykorzystaniem SSE w NestJS upraszcza komunikację pomiędzy serwerem a klientami. Ta metoda zmniejsza obciążenie serwera w porównaniu do ciągłego odpytywania i umożliwia precyzyjne kierowanie powiadomień. Na przykład narzędzie HR może powiadomić 200 pracowników działu sprzedaży o nowych kuponach, nie przeszkadzając innym. 🎯

Dzięki narzędziom takim jak BullMQ i Prisma ta konfiguracja zapewnia asynchroniczne przetwarzanie zadań i wydajne operacje na bazach danych. Elastyczność architektury opartej na zdarzeniach sprawia, że ​​jest to skalowalne rozwiązanie spełniające różne wymagania czasu rzeczywistego, zwiększające zaangażowanie użytkowników i niezawodność systemu.

Źródła i odniesienia
  1. Szczegółowa dokumentacja dot Framework NestJS do tworzenia skalowalnych aplikacji serwerowych.
  2. Przewodnik po użyciu BullMQ do niezawodnego zarządzania kolejką zadań w aplikacjach Node.js.
  3. Urzędnik Dokumentacja Prismy do operacji na bazach danych i wykorzystania ORM.
  4. Wgląd w Zdarzenia wysyłane przez serwer (SSE) do komunikacji klient-serwer w czasie rzeczywistym.
  5. Praktyczne przykłady wdrożeń frontendu z Dokumentacja ReactJS do budowy interaktywnych interfejsów użytkownika.