Siit saate teada, kuidas luua reaalajas vestluse API, kasutades NestJS-i abil WebSocketsi võimsust.

NestJS on populaarne raamistik serveripoolsete rakenduste loomiseks Node.js-iga. NestJS sobib oma WebSocketsi toega hästi reaalajas vestlusrakenduste arendamiseks.

Niisiis, mis on WebSockets ja kuidas saate NestJS-is reaalajas vestlusrakendust luua?

Mis on WebSocketid?

WebSockets on protokoll püsivaks, reaalajas ja kahesuunaliseks suhtluseks kliendi ja serveri vahel.

Erinevalt HTTP-st, kus ühendus suletakse kliendi ja serveri vahelise päringutsükli lõppedes, WebSocketi ühendus hoitakse avatuna ja see ei sulgu isegi pärast a-le vastuse tagastamist nõuda.

Allolev pilt kujutab endast serveri ja kliendi vahelise WebSocketi kommunikatsiooni toimimist.

Kahesuunalise side loomiseks saadab klient serverile WebSocketi käepigistuse päringu. Taotluse päised sisaldavad turvalist WebSocketi võtit (Sec-WebSocket-Key) ja an Uuendus: WebSocket päis, mis koos Ühendus: uuendada päis käsib serveril uuendada protokolli HTTP-lt WebSocketile ja hoida ühendus avatud. Õppimine

instagram viewer
WebSockets JavaScriptis aitab mõistet veelgi paremini mõista.

Reaalajas vestluse API loomine NestJS WebSocketi mooduli abil

Node.js pakub kahte peamist WebSocketsi rakendust. Esimene on ws mis rakendab paljaid WebSocketsi. Ja teine ​​on socket.io, mis pakub rohkem kõrgetasemelisi funktsioone.

NestJS-il on mõlema jaoks moodulid socket.io ja ws. See artikkel kasutab socket.io moodul näidisrakenduse WebSocketi funktsioonide jaoks.

Selles projektis kasutatav kood on saadaval a GitHubi hoidla. Soovitatav on see lokaalselt kloonida, et paremini mõista kataloogistruktuuri ja näha, kuidas kõik koodid omavahel suhtlevad.

Projekti seadistamine ja installimine

Avage oma terminal ja looge uus NestJS-i rakendus, kasutades pesa uus käsk (nt. pesa uus vestlusrakendus). Käsk genereerib uue kataloogi, mis sisaldab projektifaile. Nüüd olete valmis arendusprotsessi alustama.

Looge MongoDB ühendus

Vestlussõnumite rakenduses säilitamiseks vajate andmebaasi. See artikkel kasutab MongoDB andmebaas meie NestJS-i rakenduse jaoks, ja lihtsaim viis jooksma hakkamiseks on looge pilves MongoDB klaster ja hankige oma MongoDB URL. Kopeerige URL ja salvestage see kui MONGO_URI muutuja teie .env faili.

Mongoose'i vajate ka hiljem, kui teete MongoDB-le päringuid. Installige see käivitades npm install mongoose oma terminalis.

Aastal src kausta, looge fail nimega mongo.config.ts ja kleepige sinna järgmine kood.

importida { registerAs } alates'@nestjs/config';

/**
* Mongo andmebaasi ühenduse konfiguratsioon
*/

eksportidavaikimisi registerAs('mongodb', () => {
konst { MONGO_URI } = process.env; // .env-failist
tagasi {
uri:`${MONGO_URI}`,
};
});

Sinu projekt main.ts fail peaks välja nägema selline:

importida { NestFactory } alates'@nestjs/core';
importida { AppModule } alates'./app.module';
importida * nagu cookieParser alates'cookie-parser'
importida kiiver alates'kiiver'
importida { Logger, ValidationPipe } alates„@nestjs/common”;
importida { setupSwagger } alates'./utils/swagger';
importida { HttpExceptionFilter } alates'./filters/http-exception.filter';

asünkrfunktsioonibootstrap() {
konst rakendus = ootama NestFactory.create (AppModule, { cors: tõsi });
app.enableCors({
päritolu: '*',
volikirjad: tõsi
})
app.use (cookieParser())
app.useGlobalPipes(
uus ValidationPipe({
valge nimekiri: tõsi
})
)
konst metsaraie = uus Logija('peamine')

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

setupSwagger (rakendus)
app.use (kiiver())

ootama app.listen (AppModule.port)

// logi dokumendid
konst baseUrl = AppModule.getBaseUrl (rakendus)
konst url = `http://${baseUrl}:${AppModule.port}`
logger.log(API dokumentatsioon on saadaval aadressil ${url}/docs`);
}
bootstrap();

Vestlusmooduli loomine

Reaalajas vestluse funktsiooniga alustamiseks peate esmalt installima NestJS WebSocketsi paketid. Seda saab teha, käivitades terminalis järgmise käsu.

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

Pärast pakettide installimist peate looma vestlusmooduli, käivitades järgmised käsud

nest g mooduli vestlused
nest g kontrolleri vestlused
nest g teenusevestlused

Kui moodul on loodud, on järgmine samm luua NestJS-is WebSocketsi ühendus. Loo chat.gateway.ts faili sees vestlused kausta, siin on lüüsi, mis saadab ja võtab vastu sõnumeid.

Kleepige järgmine kood chat.gateway.ts.

importida {
Message Body,
Telli sõnum,
WebSocketGateway,
WebSocketServer,
} alates'@nestjs/websockets';
importida { Server } alates'socket.io';

@WebSocketGateway()
eksportidaklassChatGateway{
@WebSocketServer()
server: Server;
// kuulake send_message sündmusi
@Telli Sõnum('saada sõnum')
listenForMessages(@MessageBody() sõnum: string) {
see.server.sockets.emit('receive_message', sõnum);
}
}

Ühendatud kasutajate autentimine

Autentimine on veebirakenduste oluline osa ja see ei erine ka vestlusrakenduste puhul. Funktsioon kliendiühenduste autentimiseks pistikupesaga on leitav chats.service.ts nagu siin näidatud:

@Süstitav()
eksportidaklassVestlusteenus{
konstruktor(privaatne autentimisteenus: AuthService) {}

asünkr getUserFromSocket (socket: Socket) {
lase auth_token = socket.handshake.headers.authorization;
// hankige märk ise ilma kandjata
auth_token = auth_token.split(' ')[1];

konst kasutaja = see.authService.getUserFromAuthenticationToken(
auth_token
);

kui (!kasutaja) {
viskamauus WsException("Valed volikirjad.");
}
tagasi kasutaja;
}
}

The getUserFromSocket meetod kasutab getUserFromAuthenticationToken et saada praegu sisse logitud kasutaja JWT-märgist, eraldades kandja märgi. The getUserFromAuthenticationToken funktsioon on rakendatud auth.service.ts fail nagu siin näidatud:

avalik asünkr getUserFromAuthenticationToken (märk: string) {
konst kasulik koormus: JwtPayload = see.jwtService.verify (token, {
saladus: see.configService.get(„JWT_ACCESS_TOKEN_SECRET”),
});

konst userId = payload.sub

kui (kasutaja ID) {
tagasisee.usersService.findById (userId);
}
}

Praegune pistikupesa edastatakse parameetrina getUserFromSocket kui käepide Ühendus meetod ChatGateway rakendab OnGatewayConnection liides. See võimaldab saada sõnumeid ja teavet hetkel ühendatud kasutaja kohta.

Allolev kood näitab seda:

// chat.gateway.ts
@WebSocketGateway()
eksportidaklassChatGatewayrakendabOnGatewayConnection{
@WebSocketServer()
server: Server;

konstruktor(privaatvestlusteenus: ChatsService) {}

asünkr handConnection (pesa: Socket) {
ootamasee.chatsService.getUserFromSocket (socket)
}

@Telli Sõnum('saada sõnum')
asünkr listenForMessages(@MessageBody() sõnum: string, @ConnectedSocket() socket: Socket) {

konst kasutaja = ootamasee.chatsService.getUserFromSocket (socket)
see.server.sockets.emit('receive_message', {
sõnum,
kasutaja
});
}
}

Saate viidata autentimissüsteemiga seotud failidele ülaltoodud jaotises GitHubi hoidla juurutamise paremaks mõistmiseks, et näha täielikke koode (sh impordid).

Püsivad vestlused andmebaasis

Selleks, et kasutajad näeksid oma sõnumside ajalugu, vajate sõnumite salvestamiseks skeemi. Looge uus fail nimega message.schema.ts ja kleepige sellesse allolev kood (pidage meeles, et importige oma kasutaja skeem või vaadake hoidlast).

importida { Kasutaja } alates'./../users/schemas/user.schema';
importida { Prop, Schema, SchemaFactory } alates"@nestjs/mongoose";
importida mangust, { dokument } alates"mongoose";

eksportida type MessageDocument = Sõnum & dokument;

@Schema({
toJSON: {
hankijad: tõsi,
virtuaalsed: tõsi,
},
ajatemplid: tõsi,
})
eksportidaklassSõnum{
@Prop({ nõutud: tõsi, ainulaadne: tõsi })
sõnum: string

@Prop({ tüüp: mangust. Skeem. Tüübid. ObjectId, viide: 'kasutaja' })
kasutaja: kasutaja
}

konst MessageSchema = SchemaFactory.createForClass (sõnum)

eksportida { Sõnumiskeem };

Allpool on toodud teenuste rakendamine uue sõnumi loomiseks ja kõigi sõnumite sisestamiseks chats.service.ts.

importida { Sõnum, Sõnumidokument } alates'./message.schema'; 
importida { Pistikupesa } alates'socket.io';
importida { AuthService } alates"./../auth/auth.service";
importida { Süstitav } alates„@nestjs/common”;
importida { WsException } alates'@nestjs/websockets';
importida { InjectModel } alates„@nestjs/mongoose”;
importida { Mudel } alates"mongoose";
importida { SõnumDto } alates'./dto/message.dto';

@Süstitav()
eksportidaklassVestlusteenus{
konstruktor(privaatne autentimisteenus: AuthService, @InjectModel (Message.name) privaatsõnumModel: mudel) {}
...
asünkr Loo Sõnum (sõnum: SõnumDto, kasutaja ID: string) {
konst uus sõnum = uussee.messageModel({...message, userId})
ootama uus Sõnum.salvesta
tagasi uus sõnum
}
asünkr getAllMessages() {
tagasisee.messageModel.find().populate('kasutaja')
}
}

The SõnumDto rakendatakse a message.dto.ts faili dto kaustas vestlused kataloog. Selle leiate ka hoidlast.

Peate lisama sõnum mudel ja skeem imporditavate toodete loendisse chats.module.ts.

importida { Sõnum, Sõnumiskeem } alates'./message.schema';
importida { Moodul } alates„@nestjs/common”;
importida { ChatGateway } alates'./chats.gateway';
importida { Vestlusteenus } alates'./chats.service';
importida { MongooseModule } alates„@nestjs/mongoose”;

@Module({
impordid: [MongooseModule.forFeature([
{ nimi: Sõnum.nimi, skeem: Sõnumiskeem }
])],
kontrollerid: [],
pakkujad: [ChatsService, ChatGateway]
})
eksportidaklassVestluste moodul{}

Lõpuks, hanki_kõik_sõnumid sündmuste töötleja on lisatud ChatGateway klassi sisse chat.gateway.ts nagu on näha järgmises koodis:

// impordib...

@WebSocketGateway()
eksportidaklassChatGatewayrakendabOnGatewayConnection{
...

@Telli Sõnum('get_all_messages')
asünkr getAllMessages(@ConnectedSocket() pesa: Socket) {

ootamasee.chatsService.getUserFromSocket (socket)
konst sõnumid = ootamasee.chatsService.getAllMessages()

see.server.sockets.emit('receive_message', sõnumid);

tagasi sõnumeid
}
}

Kui ühendatud klient (kasutaja) väljastab hanki_kõik_sõnumid sündmuse korral hangitakse alla kõik nende sõnumid ja millal nad väljastavad saada sõnum, sõnum luuakse ja salvestatakse andmebaasi ning saadetakse seejärel kõigile teistele ühendatud klientidele.

Kui kõik ülaltoodud sammud on tehtud, võite käivitada rakenduse kasutades npm käivitamise algus: devja testige seda WebSocketi kliendiga, nagu Postman.

Reaalajas rakenduste loomine NestJS-iga

Kuigi reaalajas süsteemide ehitamiseks on ka teisi tehnoloogiaid, on WebSocketid väga populaarsed ja paljudel juhtudel hõlpsasti rakendatavad ning need on vestlusrakenduste jaoks parim valik.

Reaalajas kasutatavad rakendused ei piirdu ainult vestlusrakendustega, muud näited hõlmavad video voogesitust või helistamisrakendused ja reaalajas ilmarakendused ning NestJS pakub suurepäraseid tööriistu reaalajas loomiseks rakendusi.