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 (

instagram viewer
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.