Получение серверного времени через WebSockets и отображение его в Angular-приложении
В этом посте я опишу как создать веб-сокетный стрим в бэкенде на NestJS
и подписаться на него из фронтенд приложения на Angular
.
1. Устанавливаем дополнительные библиотеки
Устанавливаем NestJS
-модули для работы с websockets
.
Команды
npm install --save @nestjs/websockets @nestjs/platform-socket.io @nestjs/platform-ws
Вывод консоли
$ npm install --save @nestjs/websockets @nestjs/platform-socket.io @nestjs/platform-ws
added 4 packages, removed 2 packages, and audited 2938 packages in 1m
360 packages are looking for funding
run `npm fund` for details
42 vulnerabilities (21 low, 3 moderate, 18 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
Run `npm audit` for details.
2. Создаем контроллер который отдает серверное время
Контроллер имеет метод выдачи текущего времени и веб-сокет который каждую секунду возвращает текущее время бэкенда.
Создаем файл apps/server/src/app/time.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AllowEmptyUser } from '@nestjs-mod/authorizer';
import { ApiOkResponse } from '@nestjs/swagger';
import { OnGatewayConnection, SubscribeMessage, WebSocketGateway, WsResponse } from '@nestjs/websockets';
import { interval, map, Observable } from 'rxjs';
export const ChangeTimeStream = 'ChangeTimeStream';
@AllowEmptyUser()
@WebSocketGateway({
cors: {
origin: '*',
},
path: '/ws/time',
transports: ['websocket'],
})
@Controller()
export class TimeController implements OnGatewayConnection {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
handleConnection(client: any, ...args: any[]) {
client.headers = args[0].headers;
}
@Get('/time')
@ApiOkResponse({ type: Date })
time() {
return new Date();
}
@SubscribeMessage(ChangeTimeStream)
onChangeTimeStream(): Observable<WsResponse<Date>> {
return interval(1000).pipe(
map(() => ({
data: new Date(),
event: ChangeTimeStream,
}))
);
}
}
3. Добавляем контроллер в AppModule
Так как контроллер также включает в себя логику гейтвея, то провайдим контроллер в секции controllers
и providers
.
Обновляем файл apps/server/src/app/app.module.ts
import { createNestModule, NestModuleCategory } from '@nestjs-mod/common';
import { WebhookModule } from '@nestjs-mod-fullstack/webhook';
import { PrismaModule } from '@nestjs-mod/prisma';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TimeController } from './time.controller';
export const { AppModule } = createNestModule({
moduleName: 'AppModule',
moduleCategory: NestModuleCategory.feature,
imports: [
WebhookModule.forFeature({
featureModuleName: 'app',
}),
PrismaModule.forFeature({
contextName: 'app',
featureModuleName: 'app',
}),
...(process.env.DISABLE_SERVE_STATIC
? []
: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'client', 'browser'),
}),
]),
],
controllers: [AppController, TimeController],
providers: [AppService, TimeController],
});
4. Пересоздаем SDK для фронтенда и тестов
Команды
npm run generate