feat: implement messaging functionality with real-time updates
- Introduced a messaging module on the backend using NestJS, including repository, service, controller, DTOs, and WebSocket Gateway. - Developed a frontend messaging page with conversation management, real-time message handling, and chat UI. - Implemented `MessageService` for API integrations and `SocketProvider` for real-time WebSocket updates. - Enhanced database schema to support conversations, participants, and messages with Drizzle ORM.
This commit is contained in:
82
backend/src/realtime/events.gateway.ts
Normal file
82
backend/src/realtime/events.gateway.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Logger } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import {
|
||||
OnGatewayConnection,
|
||||
OnGatewayDisconnect,
|
||||
OnGatewayInit,
|
||||
WebSocketGateway,
|
||||
WebSocketServer,
|
||||
} from "@nestjs/websockets";
|
||||
import { getIronSession } from "iron-session";
|
||||
import { Server, Socket } from "socket.io";
|
||||
import { getSessionOptions, SessionData } from "../auth/session.config";
|
||||
import { JwtService } from "../crypto/services/jwt.service";
|
||||
|
||||
@WebSocketGateway({
|
||||
cors: {
|
||||
origin: "*",
|
||||
credentials: true,
|
||||
},
|
||||
})
|
||||
export class EventsGateway
|
||||
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
|
||||
{
|
||||
@WebSocketServer()
|
||||
server!: Server;
|
||||
|
||||
private readonly logger = new Logger(EventsGateway.name);
|
||||
|
||||
constructor(
|
||||
private readonly jwtService: JwtService,
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
afterInit(_server: Server) {
|
||||
this.logger.log("WebSocket Gateway initialized");
|
||||
}
|
||||
|
||||
async handleConnection(client: Socket) {
|
||||
try {
|
||||
// Simuler un objet Request/Response pour iron-session
|
||||
const req: any = {
|
||||
headers: client.handshake.headers,
|
||||
};
|
||||
const res: any = {
|
||||
setHeader: () => {},
|
||||
getHeader: () => {},
|
||||
};
|
||||
|
||||
const session = await getIronSession<SessionData>(
|
||||
req,
|
||||
res,
|
||||
getSessionOptions(this.configService.get("SESSION_PASSWORD") as string),
|
||||
);
|
||||
|
||||
if (!session.accessToken) {
|
||||
this.logger.warn(`Client ${client.id} unauthorized connection`);
|
||||
client.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = await this.jwtService.verifyJwt(session.accessToken);
|
||||
client.data.user = payload;
|
||||
|
||||
// Rejoindre une room personnelle pour les notifications
|
||||
client.join(`user:${payload.sub}`);
|
||||
|
||||
this.logger.log(`Client connected: ${client.id} (User: ${payload.sub})`);
|
||||
} catch (error) {
|
||||
this.logger.error(`Connection error for client ${client.id}: ${error}`);
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
handleDisconnect(client: Socket) {
|
||||
this.logger.log(`Client disconnected: ${client.id}`);
|
||||
}
|
||||
|
||||
// Méthode utilitaire pour envoyer des messages à un utilisateur spécifique
|
||||
sendToUser(userId: string, event: string, data: any) {
|
||||
this.server.to(`user:${userId}`).emit(event, data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user