first commit
This commit is contained in:
122
src/gateways/chat.gateway.ts
Normal file
122
src/gateways/chat.gateway.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import {
|
||||
ConnectedSocket,
|
||||
MessageBody,
|
||||
OnGatewayConnection,
|
||||
OnGatewayDisconnect,
|
||||
SubscribeMessage,
|
||||
WebSocketGateway,
|
||||
WebSocketServer,
|
||||
WsException,
|
||||
} from '@nestjs/websockets';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ChatService } from '../modules/chat/chat.service';
|
||||
import { SendMessageDto } from '../modules/chat/dto/send-message.dto';
|
||||
|
||||
@WebSocketGateway({
|
||||
cors: {
|
||||
origin: '*',
|
||||
credentials: true,
|
||||
},
|
||||
namespace: 'chat',
|
||||
})
|
||||
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
||||
@WebSocketServer()
|
||||
server: Server;
|
||||
|
||||
private readonly logger = new Logger(ChatGateway.name);
|
||||
private connectedUsers = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
private readonly jwtService: JwtService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly chatService: ChatService,
|
||||
) {}
|
||||
|
||||
async handleConnection(client: Socket) {
|
||||
try {
|
||||
const token =
|
||||
client.handshake.auth?.token ||
|
||||
client.handshake.headers?.authorization?.replace('Bearer ', '');
|
||||
|
||||
if (!token) {
|
||||
client.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = this.jwtService.verify(token, {
|
||||
secret: this.configService.get<string>('jwt.secret'),
|
||||
});
|
||||
|
||||
client.data.userId = payload.sub;
|
||||
this.connectedUsers.set(payload.sub, client.id);
|
||||
this.logger.log(`User ${payload.sub} connected via WebSocket`);
|
||||
} catch {
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
handleDisconnect(client: Socket) {
|
||||
const userId = client.data.userId;
|
||||
if (userId) {
|
||||
this.connectedUsers.delete(userId);
|
||||
this.logger.log(`User ${userId} disconnected`);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeMessage('join_chat')
|
||||
async handleJoinChat(
|
||||
@ConnectedSocket() client: Socket,
|
||||
@MessageBody() data: { chatId: string },
|
||||
) {
|
||||
const userId = client.data.userId;
|
||||
if (!userId) throw new WsException('Unauthorized');
|
||||
await client.join(`chat:${data.chatId}`);
|
||||
return { event: 'joined_chat', chatId: data.chatId };
|
||||
}
|
||||
|
||||
@SubscribeMessage('leave_chat')
|
||||
async handleLeaveChat(
|
||||
@ConnectedSocket() client: Socket,
|
||||
@MessageBody() data: { chatId: string },
|
||||
) {
|
||||
await client.leave(`chat:${data.chatId}`);
|
||||
return { event: 'left_chat', chatId: data.chatId };
|
||||
}
|
||||
|
||||
@SubscribeMessage('send_message')
|
||||
async handleSendMessage(
|
||||
@ConnectedSocket() client: Socket,
|
||||
@MessageBody() data: { chatId: string } & SendMessageDto,
|
||||
) {
|
||||
const userId = client.data.userId;
|
||||
if (!userId) throw new WsException('Unauthorized');
|
||||
|
||||
const { chatId, ...msgDto } = data;
|
||||
const newMessage = await this.chatService.sendMessage(userId, chatId, msgDto);
|
||||
|
||||
this.server.to(`chat:${chatId}`).emit('new_message', newMessage);
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
@SubscribeMessage('typing')
|
||||
handleTyping(
|
||||
@ConnectedSocket() client: Socket,
|
||||
@MessageBody() data: { chatId: string; isTyping: boolean },
|
||||
) {
|
||||
const userId = client.data.userId;
|
||||
client.to(`chat:${data.chatId}`).emit('user_typing', {
|
||||
userId,
|
||||
isTyping: data.isTyping,
|
||||
});
|
||||
}
|
||||
|
||||
emitToUser(userId: string, event: string, data: any) {
|
||||
const socketId = this.connectedUsers.get(userId);
|
||||
if (socketId) {
|
||||
this.server.to(socketId).emit(event, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/gateways/gateways.module.ts
Normal file
11
src/gateways/gateways.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ChatGateway } from './chat.gateway';
|
||||
import { ChatModule } from '../modules/chat/chat.module';
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
|
||||
@Module({
|
||||
imports: [ChatModule, AuthModule],
|
||||
providers: [ChatGateway],
|
||||
exports: [ChatGateway],
|
||||
})
|
||||
export class GatewaysModule {}
|
||||
Reference in New Issue
Block a user