Adapterlar
WebSockets moduli platform-agnostik, shuning uchun WebSocketAdapter interfeysidan foydalanib o'zingizning kutubxonangizni (hatto native implementatsiyani) ulashingiz mumkin. Bu int
WebSockets moduli platform-agnostik, shuning uchun WebSocketAdapter interfeysidan foydalanib o'zingizning kutubxonangizni (hatto native implementatsiyani) ulashingiz mumkin. Bu interfeys quyidagi jadvalda tasvirlangan bir nechta metodlarni implement qilishni majbur qiladi:
create | Berilgan argumentlar asosida socket instansiyasini yaratadi |
bindClientConnect | Mijoz ulanish hodisasini bog'laydi |
bindClientDisconnect | Mijoz uzilishi hodisasini bog'laydi (ixtiyoriy*) |
bindMessageHandlers | Kirish xabarini mos xabar handleriga bog'laydi |
close | Server instansiyasini yakunlaydi |
socket.io ni kengaytirish
socket.io paketi IoAdapter klassiga o'ralgan. Adapterning asosiy funksionalligini kengaytirmoqchi bo'lsangiz-chi? Masalan, texnik talablaringiz web servisingizning bir nechta load-balance qilingan instansiyalari bo'ylab hodisalarni broadcast qilish imkoniyatini talab qiladi. Buning uchun IoAdapterni kengaytirib, socket.io serverlarini instansiyalash uchun mas'ul bo'lgan bitta metodni override qilishingiz mumkin. Avvalo, kerakli paketni o'rnatamiz.
Bir nechta load-balance qilingan instansiyalar bilan socket.io dan foydalanish uchun mijozlaringiz socket.io konfiguratsiyasida transports: ['websocket'] ni o'rnatib pollingni o'chirishingiz yoki load balanceringizda cookie asosidagi routingni yoqishingiz kerak. Faqat Redisning o'zi yetarli emas. Batafsil ma'lumot uchun here.
1$ npm i --save redis socket.io @socket.io/redis-adapterPaket o'rnatilgach, RedisIoAdapter klassini yaratishimiz mumkin.
1import { IoAdapter } from '@nestjs/platform-socket.io';
2import { ServerOptions } from 'socket.io';
3import { createAdapter } from '@socket.io/redis-adapter';
4import { createClient } from 'redis';
5
6export class RedisIoAdapter extends IoAdapter {
7 private adapterConstructor: ReturnType<typeof createAdapter>;
8
9 async connectToRedis(): Promise<void> {
10 const pubClient = createClient({ url: `redis://localhost:6379` });
11 const subClient = pubClient.duplicate();
12
13 await Promise.all([pubClient.connect(), subClient.connect()]);
14
15 this.adapterConstructor = createAdapter(pubClient, subClient);
16 }
17
18 createIOServer(port: number, options?: ServerOptions): any {
19 const server = super.createIOServer(port, options);
20 server.adapter(this.adapterConstructor);
21 return server;
22 }
23}Shundan so'ng, shunchaki yangi yaratilgan Redis adapteringizga o'ting.
1const app = await NestFactory.create(AppModule);
2const redisIoAdapter = new RedisIoAdapter(app);
3await redisIoAdapter.connectToRedis();
4
5app.useWebSocketAdapter(redisIoAdapter);Ws kutubxonasi
Yana bir mavjud adapter bu WsAdapter bo'lib, u framework va tezkor, yaxshi sinovdan o'tgan ws kutubxonasi orasida proksi sifatida ishlaydi. Bu adapter native brauzer WebSockets bilan to'liq mos va socket.io paketidan ancha tez. Afsuski, unda tayyor holatda mavjud funksiyalar sezilarli darajada kamroq. Ba'zi holatlarda esa ular shart emas.
ws kutubxonasi namespace ( socket.io ommalashtirgan aloqa kanallari) ni qo'llab-quvvatlamaydi. Biroq bu imkoniyatni bir muncha taqlid qilish uchun turli yo'llarda bir nechta ws serverlarini mount qilishingiz mumkin (masalan: @WebSocketGateway({{ '{' }} path: '/users' {{ '}' }})).
ws dan foydalanish uchun avval kerakli paketni o'rnatishimiz kerak:
1$ npm i --save @nestjs/platform-wsPaket o'rnatilgach, adapterga o'tishimiz mumkin:
1const app = await NestFactory.create(AppModule);
2app.useWebSocketAdapter(new WsAdapter(app));WsAdapter@nestjs/platform-ws paketidan import qilinadi.
wsAdapter {{ '{' }} event: string, data: any {{ '}' }} formatidagi xabarlarni qayta ishlash uchun mo'ljallangan. Agar xabarlarni boshqa formatda qabul qilib, qayta ishlashingiz kerak bo'lsa, ularni talab qilingan formatga aylantirish uchun message parserni sozlashingiz kerak.
1const wsAdapter = new WsAdapter(app, {
2 // To handle messages in the [event, data] format
3 messageParser: (data) => {
4 const [event, payload] = JSON.parse(data.toString());
5 return { event, data: payload };
6 },
7});Muqobil ravishda, adapter yaratilgandan keyin setMessageParser metodidan foydalanib message parserni sozlashingiz mumkin.
Kengaytirilgan (custom adapter)
Namoyish uchun ws kutubxonasini qo'lda integratsiya qilamiz. Aytilganidek, bu kutubxona uchun adapter allaqachon yaratilgan va @nestjs/platform-ws paketidan WsAdapter klassi sifatida ochiq. Soddalashtirilgan implementatsiya taxminan quyidagicha ko'rinishi mumkin:
1import * as WebSocket from 'ws';
2import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
3import { MessageMappingProperties } from '@nestjs/websockets';
4import { Observable, fromEvent, EMPTY } from 'rxjs';
5import { mergeMap, filter } from 'rxjs/operators';
6
7export class WsAdapter implements WebSocketAdapter {
8 constructor(private app: INestApplicationContext) {}
9
10 create(port: number, options: any = {}): any {
11 return new WebSocket.Server({ port, ...options });
12 }
13
14 bindClientConnect(server, callback: Function) {
15 server.on('connection', callback);
16 }
17
18 bindMessageHandlers(
19 client: WebSocket,
20 handlers: MessageMappingProperties[],
21 process: (data: any) => Observable<any>,
22 ) {
23 fromEvent(client, 'message')
24 .pipe(
25 mergeMap(data => this.bindMessageHandler(data, handlers, process)),
26 filter(result => result),
27 )
28 .subscribe(response => client.send(JSON.stringify(response)));
29 }
30
31 bindMessageHandler(
32 buffer,
33 handlers: MessageMappingProperties[],
34 process: (data: any) => Observable<any>,
35 ): Observable<any> {
36 const message = JSON.parse(buffer.data);
37 const messageHandler = handlers.find(
38 handler => handler.message === message.event,
39 );
40 if (!messageHandler) {
41 return EMPTY;
42 }
43 return process(messageHandler.callback(message.data));
44 }
45
46 close(server) {
47 server.close();
48 }
49}ws kutubxonasining imkoniyatlaridan foydalanmoqchi bo'lsangiz, o'zingiznikini yaratish o'rniga ichki WsAdapterdan foydalaning.
Shundan so'ng, useWebSocketAdapter() metodi orqali custom adapterni sozlashimiz mumkin:
1const app = await NestFactory.create(AppModule);
2app.useWebSocketAdapter(new WsAdapter(app));Misol
WsAdapterdan foydalanadigan ishlovchi misol here mavjud.