Naučite se zgraditi API za klepet v realnem času, ki izkorišča moč WebSockets z uporabo NestJS.
NestJS je priljubljeno ogrodje za izdelavo strežniških aplikacij z Node.js. S podporo za WebSockets je NestJS zelo primeren za razvoj aplikacij za klepet v realnem času.
Torej, kaj so WebSockets in kako lahko zgradite aplikacijo za klepet v realnem času v NestJS?
Kaj so WebSockets?
WebSockets so protokol za trajno dvosmerno komunikacijo v realnem času med odjemalcem in strežnikom.
Za razliko od HTTP, kjer se povezava prekine, ko se zaključi cikel zahteve med odjemalcem in strežnikom, povezava WebSocket ostane odprta in se ne zapre niti potem, ko je bil vrnjen odgovor za a prošnja.
Spodnja slika je vizualizacija delovanja komunikacije WebSocket med strežnikom in odjemalcem:
Za vzpostavitev dvosmerne komunikacije odjemalec strežniku pošlje zahtevo za rokovanje WebSocket. Glave zahtev vsebujejo varen ključ WebSocket (Sec-WebSocket-Key), in an Nadgradnja: WebSocket glavo, ki skupaj z Povezava: Nadgradnja
pove strežniku, naj nadgradi protokol s HTTP na WebSocket in ohrani povezavo odprto. Učenje o WebSockets v JavaScriptu pomaga še bolje razumeti koncept.Izdelava API-ja za klepet v realnem času z uporabo modula NestJS WebSocket
Node.js ponuja dve glavni implementaciji WebSockets. Prvi je ws ki implementira gole WebSockets. In drugi je socket.io, ki zagotavlja več funkcij na visoki ravni.
NestJS ima module za oboje socket.io in ws. Ta članek uporablja socket.io modul za funkcije WebSocket vzorčne aplikacije.
Koda, uporabljena v tem projektu, je na voljo v a Repozitorij GitHub. Priporočljivo je, da ga klonirate lokalno, da boste bolje razumeli strukturo imenika in videli, kako vse kode medsebojno delujejo.
Nastavitev in namestitev projekta
Odprite terminal in ustvarite novo aplikacijo NestJS z uporabo gnezdo novo ukaz (npr. nest nova aplikacija za klepet). Ukaz ustvari nov imenik, ki vsebuje projektne datoteke. Zdaj ste pripravljeni začeti razvojni proces.
Nastavite povezavo MongoDB
Če želite obdržati sporočila klepeta v aplikaciji, potrebujete bazo podatkov. Ta članek uporablja baze podatkov MongoDB za našo aplikacijo NestJS, in najlažji način, da začnete teči, je nastavite gručo MongoDB v oblaku in dobite svoj URL MongoDB. Kopirajte URL in ga shranite kot MONGO_URI spremenljivka v vašem .env mapa.
Mongoose boste potrebovali tudi pozneje, ko boste postavljali poizvedbe v MongoDB. Namestite ga z zagonom npm namestite mongoose v vašem terminalu.
V src ustvarite datoteko z imenom mongo.config.ts in vanj prilepite naslednjo kodo.
uvoz { registerAs } od'@nestjs/config';
/**
* Konfiguracija povezave z bazo podatkov Mongo
*/
izvozprivzeto registerAs('mongodb', () => {
konst {MONGO_URI} = process.env; // iz datoteke .env
vrnitev {
uri:`${MONGO_URI}`,
};
});
Tvoj projekt main.ts datoteka bi morala izgledati takole:
uvoz { NestFactory } od'@nestjs/core';
uvoz { AppModule } od'./app.module';
uvoz * kot cookieParser od'razčlenjevalnik piškotkov'
uvoz čelada od'čelada'
uvoz {Logger, ValidationPipe} od'@nestjs/common';
uvoz { setupSwagger } od'./utils/swagger';
uvoz {HttpExceptionFilter} od'./filters/http-exception.filter';asinhfunkcijobootstrap() {
konst aplikacija = čakati NestFactory.create (AppModule, { cors: prav });
app.enableCors({
izvor: '*',
poverilnice: prav
})
app.use (cookieParser())
app.useGlobalPipes(
novo ValidationPipe({
beli seznam: prav
})
)
konst zapisovalnik = novo Logger ('Glavni')app.setGlobalPrefix('api/v1')
app.useGlobalFilters(novo HttpExceptionFilter());setupSwagger (aplikacija)
app.use (čelada())čakati app.listen (AppModule.port)
// zapis dokumentov
konst baseUrl = AppModule.getBaseUrl (aplikacija)
konst url = `http://${baseUrl}:${AppModule.port}`
logger.log(`Dokumentacija API-ja je na voljo na ${url}/docs`);
}
bootstrap();
Gradnja modula za klepet
Če želite začeti s funkcijo klepeta v realnem času, je prvi korak namestitev paketov NestJS WebSockets. To lahko storite tako, da v terminalu zaženete naslednji ukaz.
npm namestite @nestjs/websockets @nestjs/platform-socket.io @types/socket.io
Po namestitvi paketov morate ustvariti modul za klepete z izvajanjem naslednjih ukazov
klepeti modula nest g
klepeti krmilnika nest g
klepeti storitev nest g
Ko končate z generiranjem modula, je naslednji korak ustvarjanje povezave WebSockets v NestJS. Ustvariti chat.gateway.ts datoteka znotraj klepeti mapo, tukaj je implementiran prehod, ki pošilja in sprejema sporočila.
Prilepite naslednjo kodo v chat.gateway.ts.
uvoz {
MessageBody,
Naroči sporočilo,
WebSocketGateway,
WebSocketServer,
} od'@nestjs/websockets';
uvoz { Strežnik } od'socket.io';
@WebSocketGateway()
izvozrazredChatGateway{
@WebSocketServer()
strežnik: strežnik;
// poslušaj dogodke send_message
@SubscribeMessage('Pošlji sporočilo')
listenForMessages(@MessageBody() sporočilo: niz) {
to.server.sockets.emit('receive_message', sporočilo);
}
}
Preverjanje pristnosti povezanih uporabnikov
Preverjanje pristnosti je bistveni del spletnih aplikacij in nič drugače ni za aplikacijo za klepet. Funkcijo za preverjanje pristnosti odjemalskih povezav z vtičnico najdete v chats.service.ts kot je prikazano tukaj:
@Injectable()
izvozrazredChatsService{
konstruktor(private authService: AuthService) {}asinh getUserFromSocket (vtičnica: vtičnica) {
pustiti auth_token = socket.handshake.headers.authorization;
// pridobi sam žeton brez "Nosilca"
auth_token = auth_token.split(' ')[1];konst uporabnik = to.authService.getUserFromAuthenticationToken(
auth_token
);
če (!uporabnik) {
metatinovo WsException('Neveljavne poverilnice.');
}
vrnitev uporabnik;
}
}
The getUserFromSocket metoda uporablja getUserFromAuthenticationToken da pridobite trenutno prijavljenega uporabnika iz žetona JWT tako, da ekstrahirate žeton nosilca. The getUserFromAuthenticationToken funkcija je implementirana v auth.service.ts datoteko, kot je prikazano tukaj:
javnosti asinh getUserFromAuthenticationToken (žeton: niz) {
konst koristna obremenitev: JwtPayload = to.jwtService.verify (žeton, {
skrivnost: to.configService.get('JWT_ACCESS_TOKEN_SECRET'),
});konst userId = payload.sub
če (Uporabniško ime) {
vrnitevto.usersService.findById (userId);
}
}
Trenutna vtičnica se posreduje kot parameter getUserFromSocket ko handleConnection metoda ChatGateway izvaja OnGatewayConnection vmesnik. To omogoča prejemanje sporočil in informacij o trenutno povezanem uporabniku.
Spodnja koda to prikazuje:
// chat.gateway.ts
@WebSocketGateway()
izvozrazredChatGatewaypripomočkeOnGatewayConnection{
@WebSocketServer()
strežnik: strežnik;konstruktor(private chatsService: ChatsService) {}
asinh handleConnection (vtičnica: vtičnica) {
čakatito.chatsService.getUserFromSocket (vtičnica)
}@SubscribeMessage('Pošlji sporočilo')
asinh listenForMessages(@MessageBody() sporočilo: niz, @ConnectedSocket() vtičnica: vtičnica) {
konst uporabnik = čakatito.chatsService.getUserFromSocket (vtičnica)
to.server.sockets.emit('receive_message', {
sporočilo,
uporabnik
});
}
}
Lahko se sklicujete na datoteke, vključene v sistem za preverjanje pristnosti zgoraj v Repozitorij GitHub za ogled celotnih kod (vključno z uvozi), za boljše razumevanje implementacije.
Vztrajanje klepetov v zbirko podatkov
Da bi uporabniki videli svojo zgodovino sporočanja, potrebujete shemo za shranjevanje sporočil. Ustvari novo datoteko z imenom message.schema.ts in vanj prilepite spodnjo kodo (ne pozabite uvoziti svojega uporabniško shemo ali si ga oglejte v skladišču).
uvoz { Uporabnik } od'./../users/schemas/user.schema';
uvoz {Prop, Schema, SchemaFactory} od"@nestjs/mongoose";
uvoz mungos, { Dokument } od"mungos";izvoz type MessageDocument = Sporočilo & Dokument;
@Shema({
toJSON: {
pridobivalci: prav,
virtualni: prav,
},
časovni žigi: prav,
})
izvozrazredSporočilo{
@Prop({ potrebno: prav, edinstveno: prav })
sporočilo: niz@Prop({ vrsta: mungos. Shema. Vrste. ObjectId, ref: 'Uporabnik' })
uporabnik: uporabnik
}konst MessageSchema = SchemaFactory.createForClass (Sporočilo)
izvoz {Shema sporočila};
Spodaj je implementacija storitev za ustvarjanje novega sporočila in vnos vseh sporočil chats.service.ts.
uvoz { Sporočilo, MessageDocument } od'./message.schema';
uvoz { Socket } od'socket.io';
uvoz { AuthService } od'./../auth/auth.service';
uvoz { Za injiciranje } od'@nestjs/common';
uvoz {WsException} od'@nestjs/websockets';
uvoz {InjectModel} od'@nestjs/mongoose';
uvoz { Model } od'mungos';
uvoz { MessageDto } od'./dto/message.dto';
@Injectable()
izvozrazredChatsService{
konstruktor(private authService: AuthService, @InjectModel (Message.name) zasebno sporočiloModel: Model) {}
...
asinh createMessage (sporočilo: MessageDto, Uporabniško ime: vrvica) {
konst novo sporočilo = novoto.messageModel({...sporočilo, userId})
čakati newMessage.save
vrnitev novoSporočilo
}
asinh getAllMessages() {
vrnitevto.messageModel.find().populate('uporabnik')
}
}
The MessageDto se izvaja v a sporočilo.dto.ts datoteka v dto mapo v klepeti imenik. Najdete ga tudi v repozitoriju.
Dodati morate sporočilo model in shemo na seznam uvozov v chats.module.ts.
uvoz { Sporočilo, Shema sporočila } od'./message.schema';
uvoz { Modul } od'@nestjs/common';
uvoz { ChatGateway } od'./chats.gateway';
uvoz { ChatsService } od'./chats.service';
uvoz { MongooseModule } od'@nestjs/mongoose';
@Module({
uvozi: [MongooseModule.forFeature([
{ ime: ime.sporočila, shema: Shema sporočila }
])],
krmilniki: [],
ponudniki: [ChatsService, ChatGateway]
})
izvozrazredChatsModule{}
Končno, get_all_messages obdelovalnik dogodkov je dodan v ChatGateway razred v chat.gateway.ts kot je razvidno iz naslednje kode:
// uvozi ...
@WebSocketGateway()
izvozrazredChatGatewaypripomočkeOnGatewayConnection{
...@SubscribeMessage('get_all_messages')
asinh getAllMessages(@ConnectedSocket() vtičnica: vtičnica) {čakatito.chatsService.getUserFromSocket (vtičnica)
konst sporočila = čakatito.chatsService.getAllMessages()to.server.sockets.emit('receive_message', sporočila);
vrnitev sporočila
}
}
Ko povezani odjemalec (uporabnik) odda get_all_messages dogodka, bodo pridobljena vsa njihova sporočila in ko oddajo Pošlji sporočilo, sporočilo je ustvarjeno in shranjeno v bazi podatkov ter nato poslano vsem drugim povezanim odjemalcem.
Ko opravite vse zgornje korake, lahko zaženete aplikacijo z uporabo npm run start: dev, in ga preizkusite z odjemalcem WebSocket, kot je Postman.
Gradnja aplikacij v realnem času z NestJS
Čeprav obstajajo druge tehnologije za gradnjo sistemov v realnem času, so WebSockets v mnogih primerih zelo priljubljeni in enostavni za implementacijo ter so najboljša možnost za aplikacije za klepet.
Aplikacije v realnem času niso omejene samo na aplikacije za klepet, drugi primeri vključujejo pretakanje videa ali klicne aplikacije in vremenske aplikacije v živo, NestJS pa ponuja odlično orodje za gradnjo v realnem času aplikacije.