Ismerje meg, hogyan hozhat létre valós idejű csevegési API-t a WebSockets erejének kihasználásával a NestJS használatával.
A NestJS egy népszerű keretrendszer a Node.js segítségével kiszolgálóoldali alkalmazások létrehozásához. A WebSockets támogatásával a NestJS kiválóan alkalmas valós idejű csevegőalkalmazások fejlesztésére.
Tehát mik azok a WebSockets, és hogyan építhetsz valós idejű csevegőalkalmazást a NestJS-ben?
Mik azok a WebSockets?
A WebSockets a kliens és a szerver közötti állandó, valós idejű és kétirányú kommunikáció protokollja.
Ellentétben a HTTP-vel, ahol a kapcsolat bezárul, amikor a kérésciklus befejeződik az ügyfél és a szerver között, a WebSocket kapcsolat nyitva marad, és nem záródik be még azután sem, hogy a kérés.
Az alábbi kép azt mutatja be, hogyan működik a WebSocket kommunikáció a szerver és az ügyfél között:
A kétirányú kommunikáció létrehozásához az ügyfél WebSocket kézfogási kérést küld a kiszolgálónak. A kérés fejlécei tartalmaznak egy biztonságos WebSocket kulcsot (
Sec-WebSocket-Key), és egy Frissítés: WebSocket fejléc, amely együtt a Csatlakozás: Frissítés fejléc utasítja a szervert, hogy frissítse a protokollt HTTP-ről WebSocketre, és tartsa nyitva a kapcsolatot. Tanulni valamiről WebSockets JavaScriptben segít a fogalom még jobb megértésében.Valós idejű csevegési API létrehozása a NestJS WebSocket Module segítségével
A Node.js két fő WebSockets megvalósítást biztosít. Az első az ws amely csupasz WebSocketeket valósít meg. A második pedig az socket.io, amely több magas szintű szolgáltatást biztosít.
A NestJS mindkettőhöz rendelkezik modulokkal socket.io és ws. Ez a cikk a socket.io modul a példaalkalmazás WebSocket funkcióihoz.
A projektben használt kód elérhető a GitHub adattár. Javasoljuk, hogy helyileg klónozza, hogy jobban megértse a címtárszerkezetet, és megnézze, hogyan hatnak egymásra a kódok.
Projekt beállítása és telepítése
Nyissa meg a terminált, és hozzon létre egy új NestJS alkalmazást a fészek új parancs (pl. új csevegőalkalmazás beágyazása). A parancs létrehoz egy új könyvtárat, amely tartalmazza a projektfájlokat. Most készen áll a fejlesztési folyamat elindítására.
MongoDB kapcsolat beállítása
A csevegési üzenetek alkalmazásban való megőrzéséhez adatbázisra van szüksége. Ez a cikk használja a MongoDB adatbázis a NestJS alkalmazásunkhoz, és a futás legegyszerűbb módja az állítson be egy MongoDB-fürtöt a felhőben és megkapja a MongoDB URL-jét. Másolja ki az URL-t, és tárolja a MONGO_URI változó a te .env fájlt.
Később is szüksége lesz a Mongoose-ra, amikor lekérdezi a MongoDB-t. Telepítse futtatással npm install mongoose a termináljában.
Ban,-ben src mappát, hozzon létre egy fájlt mongo.config.ts és illessze be a következő kódot.
import { registerAs } tól től"@nestjs/config";
/**
* Mongo adatbázis-kapcsolat konfigurációja
*/
exportalapértelmezett registerAs("mongodb", () => {
const { MONGO_URI } = process.env; // .env fájlból
Visszatérés {
uri:`${MONGO_URI}`,
};
});
A te projekted fő.ts a fájlnak így kell kinéznie:
import { NestFactory } tól től"@nestjs/core";
import { AppModule } tól től"./app.module";
import * mint cookieParser tól től"cookie-parser"
import sisak tól től'sisak'
import { Logger, ValidationPipe } tól től"@nestjs/common";
import { setupSwagger } tól től"./utils/swagger";
import { HttpExceptionFilter } tól től'./filters/http-exception.filter';asyncfunkcióbootstrap() {
const app = várja NestFactory.create (AppModule, { cors: igaz });
app.enableCors({
eredet: '*',
hitelesítő adatok: igaz
})
app.use (cookieParser())
app.useGlobalPipes(
új ValidationPipe({
fehérlista: igaz
})
)
const logger = új Logger('Fő')app.setGlobalPrefix("api/v1")
app.useGlobalFilters(új HttpExceptionFilter());setupSwagger (alkalmazás)
app.use (sisak())várja app.listen (AppModule.port)
// naplódokumentumok
const baseUrl = AppModule.getBaseUrl (alkalmazás)
const url = `http://${baseUrl}:${AppModule.port}`
logger.log(`Az API-dokumentáció elérhető a következő címen: ${url}/docs`);
}
bootstrap();
A Chat modul felépítése
A valós idejű csevegési funkció használatának megkezdéséhez az első lépés a NestJS WebSockets csomagok telepítése. Ezt a következő parancs futtatásával teheti meg a terminálban.
npm telepítés @nestjs/websockets @nestjs/platform-socket.io @types/socket.io
A csomagok telepítése után létre kell hozni a chat modult a következő parancsok futtatásával
nest g modul chateket
nest g kontroller chat
nest g service chat
A modul létrehozása után a következő lépés a WebSockets kapcsolat létrehozása a NestJS-ben. Hozzon létre egy chat.gateway.ts fájl belsejében chateket mappa, itt valósul meg az üzeneteket küldő és fogadó átjáró.
Illessze be a következő kódot chat.gateway.ts.
import {
MessageBody,
Feliratkozás Üzenet,
WebSocketGateway,
WebSocketServer,
} tól től"@nestjs/websockets";
import { Szerver } tól től"socket.io";
@WebSocketGateway()
exportosztályChatGateway{
@WebSocketServer()
szerver: Szerver;
// figyelje a send_message eseményeket
@SubscribeMessage('üzenet küldése')
listenForMessages(@MessageBody() üzenet: string) {
ez.server.sockets.emit('receive_message', üzenet);
}
}
Csatlakozott felhasználók hitelesítése
A hitelesítés a webalkalmazások elengedhetetlen része, és nincs ez másként a chat-alkalmazások esetében sem. A sockethez fűződő kliens kapcsolatok hitelesítésének funkciója itt található chats.service.ts ahogy itt látható:
@Injektálható()
exportosztályChatsService{
konstruktőr(privát authService: AuthService) {}async getUserFromSocket (socket: Socket) {
hagyja auth_token = socket.handshake.headers.authorization;
// magát a tokent a "hordozó nélkül"
auth_token = auth_token.split(' ')[1];const felhasználó = ez.authService.getUserFromAuthenticationToken(
auth_token
);
ha (!felhasználó) {
dobásúj WsException('Érvénytelen hitelesítő adatok.');
}
Visszatérés felhasználó;
}
}
A getUserFromSocket módszert használ getUserFromAuthenticationToken hogy az aktuálisan bejelentkezett felhasználót lekérje a JWT tokenről a Bearer token kibontásával. A getUserFromAuthenticationToken funkció a auth.service.ts fájl az itt látható módon:
nyilvános async getUserFromAuthenticationToken (token: string) {
const hasznos teher: JwtPayload = ez.jwtService.verify (token, {
titok: ez.configService.get("JWT_ACCESS_TOKEN_SECRET"),
});const userId = payload.sub
ha (Felhasználói azonosító) {
Visszatérésez.usersService.findById (userId);
}
}
Az aktuális socket paraméterként kerül átadásra getUserFromSocket amikor az handConnection a metódusa ChatGateway megvalósítja a OnGatewayConnection felület. Ez lehetővé teszi üzenetek és információk fogadását az éppen csatlakoztatott felhasználóról.
Az alábbi kód ezt szemlélteti:
// chat.gateway.ts
@WebSocketGateway()
exportosztályChatGatewaymegvalósítjaOnGatewayConnection{
@WebSocketServer()
szerver: Szerver;konstruktőr(privát chatsService: ChatsService) {}
async handleConnection (socket: Socket) {
várjaez.chatsService.getUserFromSocket (socket)
}@SubscribeMessage('üzenet küldése')
async listenForMessages(@MessageBody() üzenet: string, @ConnectedSocket() socket: Socket) {
const felhasználó = várjaez.chatsService.getUserFromSocket (socket)
ez.server.sockets.emit('receive_message', {
üzenet,
felhasználó
});
}
}
A fentiekben hivatkozhat a hitelesítési rendszerben érintett fájlokra GitHub adattár a teljes kódok megtekintéséhez (beleértve az importálást is), a megvalósítás jobb megértéséhez.
Folyamatos csevegés az adatbázisban
Ahhoz, hogy a felhasználók lássák üzenetküldési előzményeiket, szükség van egy sémára az üzenetek tárolására. Hozzon létre egy új fájlt message.schema.ts és illessze be az alábbi kódot (ne felejtse el importálni a felhasználói séma vagy nézd meg az adattárat egyért).
import { Felhasználó } tól től"./../users/schemas/user.schema";
import { Prop, Schema, SchemaFactory } tól től"@nestjs/mongoose";
import mangúz, { dokumentum } tól től"indiai menyét";export type MessageDocument = Üzenet és dokumentum;
@Séma({
toJSON: {
getterek: igaz,
virtuálisok: igaz,
},
időbélyegek: igaz,
})
exportosztályÜzenet{
@Támaszt({ kívánt: igaz, egyedi: igaz })
üzenet: string@Támaszt({ típus: mangúz. Séma. Típusok. ObjectId, ref: "Felhasználó" })
felhasználó: Felhasználó
}const MessageSchema = SchemaFactory.createForClass (Üzenet)
export { MessageSchema };
Az alábbiakban bemutatjuk az új üzenet létrehozásához és az összes üzenet beérkezéséhez szükséges szolgáltatások megvalósítását chats.service.ts.
import { Üzenet, MessageDocument } tól től'./message.schema';
import { Aljzat } tól től"socket.io";
import { AuthService } tól től"./../auth/auth.service";
import { Injekciós } tól től"@nestjs/common";
import { WsException } tól től"@nestjs/websockets";
import { InjectModel } tól től"@nestjs/mongoose";
import { Modell } tól től'indiai menyét';
import { MessageDto } tól től'./dto/message.dto';
@Injektálható()
exportosztályChatsService{
konstruktőr(private authService: AuthService, @InjectModel (Üzenet.név) privát üzenetModel: Modell) {}
...
async createMessage (üzenet: MessageDto, Felhasználói azonosító: húr) {
const újüzenet = újez.messageModel({...message, userId})
várja newMessage.save
Visszatérés új üzenet
}
async getAllMessages() {
Visszatérésez.messageModel.find().populate("felhasználó")
}
}
A ÜzenetDto a message.dto.ts fájl a dto mappában a chateket Könyvtár. Az adattárban is megtalálod.
Hozzá kell adni a üzenet modell és séma az importált termékek listájához chats.module.ts.
import { Üzenet, ÜzenetSéma } tól től'./message.schema';
import { Modul } tól től"@nestjs/common";
import { ChatGateway } tól től"./chats.gateway";
import { ChatsService } tól től'./chats.service';
import { MongooseModule } tól től"@nestjs/mongoose";
@Module({
importok: [MongooseModule.forFeature([
{ név: Üzenet.név, séma: MessageSchema }
])],
vezérlők: [],
szolgáltatók: [ChatsService, ChatGateway]
})
exportosztályChatsModule{}
Végül a get_all_messages eseménykezelő hozzáadódik a ChatGateway osztályba be chat.gateway.ts ahogy az a következő kódban látható:
// import...
@WebSocketGateway()
exportosztályChatGatewaymegvalósítjaOnGatewayConnection{
...@SubscribeMessage("get_all_messages")
async getAllMessages(@ConnectedSocket() socket: Socket) {várjaez.chatsService.getUserFromSocket (socket)
const üzenetek = várjaez.chatsService.getAllMessages()ez.server.sockets.emit('receive_message', üzenetek);
Visszatérés üzenetek
}
}
Amikor egy csatlakoztatott kliens (felhasználó) kiadja a get_all_messages esemény esetén az összes üzenet lekérésre kerül, és amikor kibocsátják üzenet küldése, üzenet jön létre és tárolódik az adatbázisban, majd elküldi az összes többi csatlakoztatott ügyfélnek.
A fenti lépések elvégzése után elindíthatja az alkalmazást a használatával npm futás indítása: dev, és tesztelje egy WebSocket klienssel, mint például a Postman.
Valós idejű alkalmazások készítése a NestJS segítségével
Bár léteznek más technológiák is a valós idejű rendszerek felépítésére, a WebSockets nagyon népszerű és sok esetben könnyen megvalósítható, és a chat alkalmazásokhoz a legjobb megoldás.
A valós idejű alkalmazások nem csak a csevegőalkalmazásokra korlátozódnak, más példák közé tartozik a video streaming ill alkalmazások hívó és élő időjárási alkalmazások, a NestJS pedig nagyszerű eszközöket biztosít a valós idejű építéshez alkalmazásokat.