NestJS kullanarak WebSockets'in gücünden yararlanan gerçek zamanlı bir sohbet API'sini nasıl oluşturacağınızı öğrenin.
NestJS, Node.js ile sunucu tarafı uygulamalar oluşturmak için popüler bir çerçevedir. WebSockets desteği ile NestJS, gerçek zamanlı sohbet uygulamaları geliştirmek için çok uygundur.
Peki, WebSockets nedir ve NestJS'de nasıl gerçek zamanlı bir sohbet uygulaması oluşturabilirsiniz?
WebSockets Nedir?
WebSockets, bir istemci ile bir sunucu arasında kalıcı, gerçek zamanlı ve iki yönlü iletişim için bir protokoldür.
İstemci ve sunucu arasında bir istek döngüsü tamamlandığında bağlantının kapatıldığı HTTP'den farklı olarak, bir WebSocket bağlantısı açık tutulur ve bir bağlantı için bir yanıt döndürüldükten sonra bile kapanmaz. rica etmek.
Aşağıdaki görüntü, bir sunucu ile istemci arasındaki WebSocket iletişiminin nasıl çalıştığının bir görselleştirmesidir:
Çift yönlü iletişim kurmak için, istemci sunucuya bir WebSocket el sıkışma isteği gönderir. İstek başlıkları, güvenli bir WebSocket anahtarı içerir (
Sec-WebSocket-Key), ve bir Yükseltme: WebSocket ile birlikte başlık Bağlantı: Yükseltme header, sunucuya protokolü HTTP'den WebSocket'e yükseltmesini ve bağlantıyı açık tutmasını söyler. Hakkında öğrenmek JavaScript'te WebSockets kavramın daha iyi anlaşılmasına yardımcı olur.NestJS WebSocket Modülünü Kullanarak Gerçek Zamanlı Sohbet API'si Oluşturma
Node.js, iki ana WebSockets uygulaması sağlar. İlk olarak ws çıplak WebSockets'i uygulayan. Ve ikincisi soket.io, daha üst düzey özellikler sağlar.
NestJS her ikisi için de modüllere sahiptir soket.io Ve ws. Bu makale, soket.io örnek uygulamanın WebSocket özellikleri için modül.
Bu projede kullanılan kod bir GitHub deposu. Dizin yapısını daha iyi anlamak ve tüm kodların birbiriyle nasıl etkileşime girdiğini görmek için yerel olarak klonlamanız önerilir.
Proje Kurulumu ve Kurulumu
Terminalinizi açın ve kullanarak yeni bir NestJS uygulaması oluşturun. yeni yuva komut (örn. yeni sohbet uygulamasını yerleştir). Komut, proje dosyalarını içeren yeni bir dizin oluşturur. Artık geliştirme sürecini başlatmaya hazırsınız.
MongoDB Bağlantısı Kurun
Sohbet mesajlarını uygulamada kalıcı kılmak için bir veri tabanına ihtiyacınız var. Bu makale kullanır NestJS uygulamamız için MongoDB veritabanıve koşmaya başlamanın en kolay yolu bulutta bir MongoDB kümesi kurun ve MongoDB URL'nizi alın. URL'yi kopyalayın ve şu şekilde saklayın: MONGO_URI sende değişken .env dosya.
Daha sonra MongoDB'ye sorgu yaptığınızda da Mongoose'a ihtiyacınız olacak. Çalıştırarak kurun npm mongoose'u kur terminalinizde.
İçinde kaynak adlı bir dosya oluşturun. mongo.config.ts ve içine aşağıdaki kodu yapıştırın.
içe aktarmak { kayıt olarak } itibaren"@nestjs/config";
/**
* Mongo veritabanı bağlantı yapılandırması
*/
ihracatvarsayılan Kayıt Ol('mongodb', () => {
sabit { MONGO_URI } = işlem.env; // .env dosyasından
geri dönmek {
uri:`${MONGO_URI}`,
};
});
projeniz ana.ts dosya şöyle görünmelidir:
içe aktarmak { NestFactory } itibaren"@nestjs/çekirdek";
içe aktarmak { Uygulama Modülü } itibaren'./app.module';
içe aktarmak * gibi çerez Ayrıştırıcı itibaren'çerez ayrıştırıcı'
içe aktarmak kask itibaren'kask'
içe aktarmak { Kaydedici, Doğrulama Borusu } itibaren"@nestjs/ortak";
içe aktarmak { kurulumSwagger } itibaren'./utils/havalı';
içe aktarmak { HttpExceptionFilter } itibaren'./filters/http-exception.filter';zaman uyumsuzişlevönyükleme() {
sabit uygulama = beklemek NestFactory.create (AppModule, { Korslar: doğru });
app.enableCors({
Menşei: '*',
kimlik bilgileri: doğru
})
app.use (cookieParser())
app.useGlobalPipes(
yeni Doğrulama Borusu({
beyaz liste: doğru
})
)
sabit kaydedici = yeni Ağaç kesicisi('Ana')app.setGlobalPrefix("apı/v1")
app.useGlobalFilters(yeni HttpExceptionFilter());setupSwagger (uygulama)
app.use (kask())beklemek app.listen (AppModule.port)
// günlük belgeleri
sabit baseUrl = AppModule.getBaseUrl (uygulama)
sabit url = http://${baseUrl}:${AppModule.port}`
kaydedici.log(`API Dokümantasyonu şu adreste mevcuttur: ${url}/docs`);
}
önyükleme();
Sohbet Modülünü Oluşturma
Gerçek zamanlı sohbet özelliğini kullanmaya başlamak için ilk adım NestJS WebSockets paketlerini kurmaktır. Bu, terminalde aşağıdaki komutu çalıştırarak yapılabilir.
npm kurulumu @nestjs/websockets @nestjs/platform-socket.io @types/socket.io
Paketleri kurduktan sonra aşağıdaki komutları çalıştırarak chats modülünü oluşturmanız gerekmektedir.
yuva g modülü sohbetleri
yuva g denetleyici sohbetleri
nest g hizmet sohbetleri
Modül oluşturmayı tamamladıktan sonraki adım, NestJS'de bir WebSockets bağlantısı oluşturmaktır. Oluşturmak chat.gateway.ts içindeki dosya sohbetler klasörü, burası mesaj gönderen ve alan ağ geçidinin uygulandığı yerdir.
Aşağıdaki kodu içine yapıştırın chat.gateway.ts.
içe aktarmak {
mesaj gövdesi,
Mesaja abone ol,
WebSocketAğ Geçidi,
WebSocket Sunucusu,
} itibaren"@nestjs/websockets";
içe aktarmak { Sunucu } itibaren"soket.io";
@WebSocketGateway()
ihracatsınıfChatGateway{
@WebSocketServer()
sunucu: Sunucu;
// send_message olaylarını dinle
@AboneMesaj('mesaj gönder')
listenForMessages(@MessageBody() mesaj: string) {
Bu.server.sockets.emit("mesaj_al", İleti);
}
}
Bağlı Kullanıcıların Kimlik Doğrulaması
Kimlik doğrulama, web uygulamalarının önemli bir parçasıdır ve sohbet uygulamasından farklı değildir. Sokete istemci bağlantılarının kimliğini doğrulama işlevi şurada bulunur: chats.service.ts burada gösterildiği gibi:
@Enjektabl()
ihracatsınıfSohbet Hizmeti{
inşaatçı(özel authService: AuthService) {}zaman uyumsuz getUserFromSocket (soket: Soket) {
izin vermek auth_token = socket.handshake.headers.yetkilendirme;
// belirtecin kendisini "Bearer" olmadan alın
auth_token = auth_token.split(' ')[1];sabit kullanıcı = Bu.authService.getUserFromAuthenticationToken(
auth_token
);
eğer (!kullanıcı) {
fırlatmakyeni WsException('Geçersiz kimlik bilgileri.');
}
geri dönmek kullanıcı;
}
}
bu getUserFromSocket yöntem kullanır getUserFromAuthenticationToken Bearer belirtecini çıkararak şu anda oturum açmış olan kullanıcıyı JWT belirtecinden almak için. bu getUserFromAuthenticationToken işlevinde uygulanır auth.hizmet.ts burada gösterildiği gibi dosya:
halk zaman uyumsuz getUserFromAuthenticationToken (belirteç: dize) {
sabit yük: JwtPayload = Bu.jwtService.verify (belirteç, {
gizli: Bu.configService.get("JWT_ACCESS_TOKEN_SECRET"),
});sabit userId = payload.sub
eğer (Kullanıcı kimliği) {
geri dönmekBu.usersService.findById (userId);
}
}
Mevcut soket parametre olarak iletilir. getUserFromSocket ne zaman koluBağlantı yöntemi ChatGateway uygular Ağ Geçidi Bağlantısında arayüz. Bu, o anda bağlı olan kullanıcı hakkında mesaj ve bilgi almayı mümkün kılar.
Aşağıdaki kod bunu göstermektedir:
// chat.gateway.ts
@WebSocketGateway()
ihracatsınıfChatGatewayuygularAğ Geçidi Bağlantısında{
@WebSocketServer()
sunucu: Sunucu;inşaatçı(özel sohbetlerHizmet: SohbetlerHizmet) {}
zaman uyumsuz handleConnection (soket: Soket) {
beklemekBu.chatsService.getUserFromSocket (yuva)
}@AboneMesaj('mesaj gönder')
zaman uyumsuz listenForMessages(@MessageBody() mesaj: string, @ConnectedSocket() soket: Soket) {
sabit kullanıcı = beklemekBu.chatsService.getUserFromSocket (yuva)
Bu.server.sockets.emit("mesaj_al", {
İleti,
kullanıcı
});
}
}
Yukarıdaki kimlik doğrulama sisteminde yer alan dosyalara şu adresten başvurabilirsiniz: GitHub deposu uygulamanın daha iyi anlaşılması için kodların tamamını (ithalatlar dahil) görmek için.
Veritabanında Kalıcı Sohbetler
Kullanıcıların mesajlaşma geçmişlerini görebilmeleri için, mesajları depolamak üzere bir şemaya ihtiyacınız vardır. adlı yeni bir dosya oluşturun. mesaj.şema.ts ve aşağıdaki kodu içine yapıştırın (almayı unutmayın) kullanıcı şeması veya biri için depoya bakın).
içe aktarmak { Kullanıcı } itibaren'./../users/schemas/user.schema';
içe aktarmak { Prop, Şema, SchemaFactory } itibaren"@nestjs/firavun faresi";
içe aktarmak firavun faresi, { Belge } itibaren"firavun faresi";ihracat MessageDocument yazın = Mesaj ve Belge;
@Şema({
JSON'a: {
alıcılar: doğru,
sanallar: doğru,
},
zaman damgaları: doğru,
})
ihracatsınıfİleti{
@destek({ gerekli: doğru, eşsiz: doğru })
mesaj: dizi@destek({ tip: firavun faresi. Şema. Türler. Nesne Kimliği, referans: "Kullanıcı" })
kullanıcı: Kullanıcı
}sabit MessageSchema = SchemaFactory.createForClass (Mesaj)
ihracat { Mesaj Şeması };
Aşağıda, yeni bir mesaj oluşturmak ve tüm mesajları almak için hizmetlerin bir uygulaması bulunmaktadır. chats.service.ts.
içe aktarmak { Mesaj, Mesaj Belgesi } itibaren'./mesaj.şema';
içe aktarmak { Priz } itibaren"soket.io";
içe aktarmak { Yetkilendirme Hizmeti } itibaren'./../auth/auth.service';
içe aktarmak { Enjekte edilebilir } itibaren"@nestjs/ortak";
içe aktarmak { WsException } itibaren"@nestjs/websockets";
içe aktarmak { Enjeksiyon Modeli } itibaren"@nestjs/firavun faresi";
içe aktarmak { Modeli } itibaren'firavun faresi';
içe aktarmak { MesajDto } itibaren'./dto/mesaj.dto';
@Enjektabl()
ihracatsınıfSohbet Hizmeti{
inşaatçı(özel authService: AuthService, @InjectModel (Message.name) özel mesajModel: Model) {}
...
zaman uyumsuz createMessage (mesaj: MesajDto, Kullanıcı kimliği: sicim) {
sabit yeniMesaj = yeniBu.messageModel({...message, userId})
beklemek yeniMesaj.kaydet
geri dönmek yeni Mesaj
}
zaman uyumsuz getAllMessages() {
geri dönmekBu.messageModel.find().populate("kullanıcı")
}
}
bu MesajDto bir şekilde uygulanmaktadır mesaj.dto.ts dosya dto içindeki klasör sohbetler dizin. Depoda da bulabilirsiniz.
eklemeniz gerekir İleti içe aktarma listesine model ve şema chats.module.ts.
içe aktarmak { Mesaj, Mesaj Şeması } itibaren'./mesaj.şema';
içe aktarmak { Modül } itibaren"@nestjs/ortak";
içe aktarmak { ChatGateway } itibaren'./chats.gateway';
içe aktarmak { Sohbet Hizmeti } itibaren'./chats.service';
içe aktarmak { Firavun Faresi Modülü } itibaren"@nestjs/firavun faresi";
@Modül({
içe aktarmalar: [MongooseModule.forFeature([
{ isim: Mesaj.adı, şema: Mesaj Şeması }
])],
denetleyiciler: [],
sağlayıcılar: [ChatsService, ChatGateway]
})
ihracatsınıfSohbet Modülü{}
Son olarak, get_all_messages olaylar işleyicisi eklendi ChatGateway sınıf chat.gateway.ts aşağıdaki kodda görüldüğü gibi:
// içe aktarma...
@WebSocketGateway()
ihracatsınıfChatGatewayuygularAğ Geçidi Bağlantısında{
...@AboneMesaj("tüm_mesajları al")
zaman uyumsuz getAllMessages(@ConnectedSocket() yuva: Yuva) {beklemekBu.chatsService.getUserFromSocket (yuva)
sabit mesajlar = beklemekBu.chatsService.getAllMessages()Bu.server.sockets.emit("mesaj_al", mesajlar);
geri dönmek mesajlar
}
}
Bağlı bir istemci (kullanıcı) get_all_messages olay, tüm mesajları alınacak ve yaydıkları zaman mesaj gönder, bir mesaj oluşturulur ve veritabanında saklanır ve ardından diğer tüm bağlı istemcilere gönderilir.
Yukarıdaki tüm adımları tamamladıktan sonra, uygulamanızı kullanarak başlayabilirsiniz. npm çalıştırma başlangıcı: devve Postman gibi bir WebSocket istemcisi ile test edin.
NestJS ile Gerçek Zamanlı Uygulamalar Oluşturma
Gerçek zamanlı sistemler oluşturmak için başka teknolojiler olmasına rağmen, WebSockets çok popülerdir ve çoğu durumda uygulanması kolaydır ve sohbet uygulamaları için en iyi seçenektir.
Gerçek zamanlı uygulamalar yalnızca sohbet uygulamalarıyla sınırlı değildir, diğer örnekler arasında video akışı veya arama uygulamaları ve canlı hava durumu uygulamaları ve NestJS, gerçek zamanlı oluşturmak için harika araçlar sağlar uygulamalar.