Zistite, ako vytvoriť rozhranie API na rozhovor v reálnom čase s využitím výkonu WebSockets pomocou NestJS.

NestJS je populárny rámec na vytváranie aplikácií na strane servera pomocou Node.js. Vďaka podpore WebSockets je NestJS veľmi vhodný na vývoj chatovacích aplikácií v reálnom čase.

Čo sú teda WebSockets a ako si môžete vytvoriť chatovaciu aplikáciu v reálnom čase v NestJS?

Čo sú WebSockets?

WebSockets sú protokolom pre trvalú, v reálnom čase a obojsmernú komunikáciu medzi klientom a serverom.

Na rozdiel od HTTP, kde sa spojenie uzavrie po dokončení cyklu požiadaviek medzi klientom a serverom, pripojenie WebSocket zostane otvorené a neuzavrie sa ani po vrátení odpovede žiadosť.

Obrázok nižšie je vizualizáciou toho, ako funguje komunikácia WebSocket medzi serverom a klientom:

Na vytvorenie obojsmernej komunikácie klient odošle na server požiadavku na nadviazanie spojenia WebSocket. Hlavičky požiadaviek obsahujú zabezpečený kľúč WebSocket (Sec-WebSocket-Key) a an Aktualizácia: WebSocket hlavička, ktorá spolu s

instagram viewer
Pripojenie: Upgrade hlavička hovorí serveru, aby aktualizoval protokol z HTTP na WebSocket a ponechal pripojenie otvorené. Učenie o WebSockets v JavaScripte pomáha ešte lepšie porozumieť konceptu.

Vytvorenie rozhrania API chatu v reálnom čase pomocou modulu NestJS WebSocket

Node.js poskytuje dve hlavné implementácie WebSockets. Prvým je ws ktorý implementuje holé WebSockets. A ten druhý je socket.io, ktorá poskytuje viac funkcií na vysokej úrovni.

NestJS má moduly pre oboje socket.io a ws. Tento článok používa socket.io modul pre funkcie WebSocket vzorovej aplikácie.

Kód použitý v tomto projekte je dostupný v a úložisko GitHub. Odporúča sa, aby ste ho naklonovali lokálne, aby ste lepšie pochopili štruktúru adresára a videli, ako všetky kódy navzájom spolupracujú.

Nastavenie a inštalácia projektu

Otvorte svoj terminál a vygenerujte novú aplikáciu NestJS pomocou hniezdo nové príkaz (napr. vnorte novú chatovú aplikáciu). Príkaz vygeneruje nový adresár, ktorý obsahuje súbory projektu. Teraz ste pripravení začať proces vývoja.

Nastavte pripojenie MongoDB

Ak chcete zachovať chatové správy v aplikácii, potrebujete databázu. Tento článok používa databázu MongoDB pre našu aplikáciu NestJSa najjednoduchší spôsob, ako začať behať, je nastaviť MongoDB klaster v cloude a získajte svoju adresu URL MongoDB. Skopírujte adresu URL a uložte ju ako MONGO_URI premenná vo vašom .env súbor.

Mongoose by ste potrebovali aj neskôr, keď budete zadávať dopyty do MongoDB. Nainštalujte ho spustením npm nainštalovať mongoose vo vašom termináli.

V src priečinok, vytvorte súbor s názvom mongo.config.ts a vložte do nej nasledujúci kód.

importovať { registerAs } od'@nestjs/config';

/**
* Konfigurácia pripojenia k databáze Mongo
*/

exportpredvolená registerAs('mongodb', () => {
konšt { MONGO_URI } = process.env; // zo súboru .env
vrátiť {
uri:`${MONGO_URI}`,
};
});

Váš projekt main.ts súbor by mal vyzerať takto:

importovať { NestFactory } od'@nestjs/core';
importovať { AppModule } od'./app.module';
importovať * ako cookieParser od'cookie-parser'
importovať prilba od'helma'
importovať { Logger, ValidationPipe } od'@nestjs/common';
importovať { setupSwagger } od'./utils/swagger';
importovať { HttpExceptionFilter } od'./filters/http-exception.filter';

asyncfunkciubootstrap() {
konšt aplikácia = čakať NestFactory.create (AppModule, { kor: pravda });
app.enableCors({
pôvod: '*',
poverenia: pravda
})
app.use (cookieParser())
app.useGlobalPipes(
Nový ValidationPipe({
whitelist: pravda
})
)
konšt zapisovač = Nový Logger('Hlavná')

app.setGlobalPrefix('api/v1')
app.useGlobalFilters(Nový HttpExceptionFilter());

setupSwagger (aplikácia)
app.use (helma())

čakať app.listen (AppModule.port)

// protokolovať dokumenty
konšt baseUrl = AppModule.getBaseUrl (aplikácia)
konšt url = `http://${baseUrl}:${AppModule.port}`
logger.log(`Dokumentácia API dostupná na ${url}/docs`);
}
bootstrap();

Vytvorenie modulu Chat

Ak chcete začať s funkciou chatu v reálnom čase, prvým krokom je inštalácia balíkov NestJS WebSockets. Môžete to urobiť spustením nasledujúceho príkazu v termináli.

npm install @nestjs/websockets @nestjs/platform-socket.io @types/socket.io

Po nainštalovaní balíkov musíte vygenerovať modul chatov spustením nasledujúcich príkazov

chaty s modulom nest g
chaty s ovládačom nest g
chaty služby nest g

Po dokončení generovania modulu je ďalším krokom vytvorenie pripojenia WebSockets v NestJS. Vytvor chat.gateway.ts súbor vnútri chaty priečinok, je to miesto, kde je implementovaná brána, ktorá odosiela a prijíma správy.

Vložte nasledujúci kód do chat.gateway.ts.

importovať {
MessageBody,
Správa na odber,
WebSocketGateway,
WebSocketServer,
} od'@nestjs/websockets';
importovať { Server } od'socket.io';

@WebSocketGateway()
exporttriedaChatGateway{
@WebSocketServer()
server: Server;
// počúvanie udalostí send_message
@Správa na odber('poslať správu')
listenForMessages(@MessageBody() message: string) {
toto.server.sockets.emit('receive_message', správa);
}
}

Overovanie pripojených používateľov

Autentifikácia je nevyhnutnou súčasťou webových aplikácií a nie je tomu inak ani pri chatovacej aplikácii. Funkcia na overenie pripojení klienta k soketu sa nachádza v chats.service.ts ako je znázornené tu:

@Injekčné()
exporttriedaChatsService{
konštruktér(súkromná authService: AuthService) {}

async getUserFromSocket (socket: Socket) {
nech auth_token = socket.handshake.headers.authorization;
// získajte samotný token bez "nositeľa"
auth_token = auth_token.split(' ')[1];

konšt užívateľ = toto.authService.getUserFromAuthenticationToken(
auth_token
);

ak (!user) {
hodiťNový WsException('Neplatné poverenia.');
}
vrátiť užívateľ;
}
}

The getUserFromSocket metóda používa getUserFromAuthenticationToken získať aktuálne prihláseného používateľa z tokenu JWT extrahovaním tokenu nositeľa. The getUserFromAuthenticationToken funkcia je implementovaná v auth.service.ts súbor, ako je znázornené tu:

verejnosti async getUserFromAuthenticationToken (token: string) {
konšt užitočné zaťaženie: JwtPayload = toto.jwtService.verify (token, {
tajomstvo: toto.configService.get(„JWT_ACCESS_TOKEN_SECRET“),
});

konšt userId = payload.sub

ak (ID používateľa) {
vrátiťtoto.usersService.findById (userId);
}
}

Aktuálny soket sa odovzdá ako parameter getUserFromSocket keď rukoväťPripojenie spôsob ChatGateway implementuje OnGatewayConnection rozhranie. To umožňuje prijímať správy a informácie o aktuálne pripojenom používateľovi.

Nižšie uvedený kód to ukazuje:

// chat.gateway.ts
@WebSocketGateway()
exporttriedaChatGatewaynáradiaOnGatewayConnection{
@WebSocketServer()
server: Server;

konštruktér(súkromná chatová služba: Chatová služba) {}

async handleConnection (zásuvka: Socket) {
čakaťtoto.chatsService.getUserFromSocket (zásuvka)
}

@Správa na odber('poslať správu')
async listenForMessages(@MessageBody() message: string, @ConnectedSocket() socket: Socket) {

konšt užívateľ = čakaťtoto.chatsService.getUserFromSocket (zásuvka)
toto.server.sockets.emit('receive_message', {
správa,
užívateľ
});
}
}

Môžete odkazovať na súbory zahrnuté v autentifikačnom systéme vyššie v úložisko GitHub zobraziť kompletné kódy (vrátane importov), ​​aby ste lepšie pochopili implementáciu.

Pretrvávajúce rozhovory do databázy

Aby používatelia videli svoju históriu správ, potrebujete schému na ukladanie správ. Vytvorte nový súbor s názvom message.schema.ts a vložte do nej kód uvedený nižšie (nezabudnite importovať svoj užívateľská schéma alebo si jeden pozrite v úložisku).

importovať { Používateľ } od'./../users/schemas/user.schema';
importovať { Prop, Schema, SchemaFactory } od"@nestjs/mongoose";
importovať mongoose, { dokument } od"mangusta";

export zadajte MessageDocument = Správa a dokument;

@Schema({
toJSON: {
príjemcovia: pravda,
virtuálne: pravda,
},
časové pečiatky: pravda,
})
exporttriedaSpráva{
@Prop({ požadovaný: pravda, jedinečný: pravda })
správa: reťazec

@Prop({ typu: mangusta. Schéma. Typy. ObjectId, ref: 'používateľ' })
užívateľ: Užívateľ
}

konšt MessageSchema = SchemaFactory.createForClass (Správa)

export { MessageSchema };

Nižšie je uvedená implementácia služieb na vytvorenie novej správy a prijatie všetkých správ chats.service.ts.

importovať { Message, MessageDocument } od'./message.schema'; 
importovať { Zásuvka } od'socket.io';
importovať { AuthService } od'./../auth/auth.service';
importovať { Injekčné } od'@nestjs/common';
importovať { WsException } od'@nestjs/websockets';
importovať { InjectModel } od'@nestjs/mongoose';
importovať { Model } od"mongoose";
importovať { MessageDto } od'./dto/message.dto';

@Injekčné()
exporttriedaChatsService{
konštruktér(súkromná authService: AuthService, @InjectModel (názov správy) súkromná správaModel: Model) {}
...
async createMessage (správa: MessageDto, ID používateľa: reťazec) {
konšt nová správa = Novýtoto.messageModel({...správa, userId})
čakať nováSpráva.uložiť
vrátiť Nová správa
}
async getAllMessages() {
vrátiťtoto.messageModel.find().populate('používateľ')
}
}

The MessageDto sa realizuje v a message.dto.ts súbor v dto priečinok v chaty adresár. Nájdete ho aj v úložisku.

Musíte pridať správu modelu a schémy do zoznamu importov v chats.module.ts.

importovať { Message, MessageSchema } od'./message.schema';
importovať { Modul } od'@nestjs/common';
importovať { ChatGateway } od'./chats.gateway';
importovať { ChatsService } od'./chats.service';
importovať { MongooseModule } od'@nestjs/mongoose';

@Modul({
importuje: [MongooseModule.forFeature([
{ názov: Message.name, schému: MessageSchema }
])],
ovládače: [],
poskytovatelia: [ChatsService, ChatGateway]
})
exporttriedaChatsModule{}

Nakoniec, get_all_messages obslužný program udalostí je pridaný do ChatGateway trieda v chat.gateway.ts ako je vidieť v nasledujúcom kóde:

// dovoz...

@WebSocketGateway()
exporttriedaChatGatewaynáradiaOnGatewayConnection{
...

@Správa na odber('get_all_messages')
async getAllMessages(@ConnectedSocket() socket: Socket) {

čakaťtoto.chatsService.getUserFromSocket (zásuvka)
konšt správy = čakaťtoto.chatsService.getAllMessages()

toto.server.sockets.emit('receive_message', správy);

vrátiť správy
}
}

Keď pripojený klient (používateľ) vyšle get_all_messages všetky ich správy sa načítajú a keď sa vydajú poslať správu, vytvorí sa správa a uloží sa do databázy a potom sa odošle všetkým ostatným pripojeným klientom.

Po vykonaní všetkých vyššie uvedených krokov môžete aplikáciu začať používať štart chodu npm: deva otestujte ho pomocou klienta WebSocket, ako je Postman.

Vytváranie aplikácií v reálnom čase pomocou NestJS

Hoci existujú aj iné technológie na budovanie systémov v reálnom čase, WebSockets sú v mnohých prípadoch veľmi populárne a ľahko implementovateľné a sú najlepšou voľbou pre chatovacie aplikácie.

Aplikácie v reálnom čase sa neobmedzujú len na chatovacie aplikácie, medzi ďalšie príklady patrí streamovanie videa resp aplikácie na volanie a živé aplikácie počasia a NestJS poskytuje skvelé nástroje na vytváranie v reálnom čase aplikácie.