change stracture

This commit is contained in:
AmirHossein Mahmoodi
2025-05-10 15:04:19 +03:30
parent 2ce1b136a8
commit ec28b21cf8
8 changed files with 112 additions and 25 deletions

View File

@@ -6,18 +6,28 @@ import { Socket } from 'socket.io';
import { Repository } from 'typeorm';
import { ClientConnectionDto } from './dto/clientConnection.dto';
import { SocketConnection } from './socket.entity';
import { RedisService } from 'src/redis/redis.service';
export interface ClientToken {
user_id: number;
telephone_id: string;
}
@Injectable()
export class SocketService {
private readonly logger = new Logger(SocketService.name);
private readonly onlineClients = new Map<string, string>();
constructor(
@InjectRepository(SocketConnection)
private socketConnectionRepository: Repository<SocketConnection>,
private readonly httpService: HttpService,
private readonly redisService: RedisService,
) {}
private getRedisKey(token: ClientToken): string {
return `online_clients:${token.user_id}-${token.telephone_id}`;
}
async clientConnection(data: ClientConnectionDto) {
const client = this.socketConnectionRepository.create(data);
@@ -29,14 +39,14 @@ export class SocketService {
const endpoint = eventEndpoints[data.event];
if (endpoint) {
const url = `${process.env.SERVICE_URL}${endpoint}?telephone_id=${client.client_id}`;
const url = `${process.env.SERVICE_URL}${endpoint}?telephone_id=${client.telephone_id}`;
try {
await firstValueFrom(
this.httpService.get(url, { timeout: 3000 }).pipe(retry(3)),
);
} catch (error) {
this.logger.error(
`❌ Failed to notify ${data.event} for client ${client.client_id}:`,
`❌ Failed to notify ${data.event} for client ${client.telephone_id}:`,
error.message || error,
);
}
@@ -77,15 +87,42 @@ export class SocketService {
};
}
setOnlineClient(clientId: string, socketId: string) {
this.onlineClients.set(clientId, socketId);
getClientKey(token: ClientToken): string {
return `${token.user_id}-${token.telephone_id}`;
}
removeOnlineClient(clientId: string) {
this.onlineClients.delete(clientId);
async addOnlineClient(token: any, socketId: string) {
const client = this.redisService.getClient();
const key = this.getRedisKey(token);
await client.sAdd(key, socketId);
}
getOnlineClients(): string[] {
return [...this.onlineClients.keys()];
async removeOnlineClient(token: any, socketId: string) {
const client = this.redisService.getClient();
const key = this.getRedisKey(token);
await client.sRem(key, socketId);
const count = await client.sCard(key);
if (count === 0) {
await client.del(key);
}
}
async getAllOnlineClients(): Promise<ClientToken[]> {
const client = this.redisService.getClient();
const keys = await client.keys('online_clients:*');
return keys.map((key) => {
const [user_id, telephone_id] = key.split(':')[1].split('-').map(Number);
return { user_id, telephone_id };
});
}
isValidToken(token: any): token is ClientToken {
return (
token &&
typeof token.user_id === 'number' &&
typeof token.telephone_id === 'string' &&
!isNaN(token.user_id) &&
!isNaN(token.telephone_id)
);
}
}