Redis можно использовать как драйвер для кэширования запросов?
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config'; // Используем ConfigModule для переменных окружения
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
type: 'postgres', // или 'mysql', 'mariadb' и т.д.
host: configService.get<string>('DB_HOST'),
port: configService.get<number>('DB_PORT'),
username: configService.get<string>('DB_USERNAME'),
password: configService.get<string>('DB_PASSWORD'),
database: configService.get<string>('DB_NAME'),
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize: true, // Внимание: false для production
logging: false,
// --- Настройки кэширования Redis ---
cache: {
type: 'ioredis', // Используем установленный ioredis
duration: 60000, // Время жизни кэша по умолчанию (в миллисекундах)
options: {
host: configService.get<string>('REDIS_HOST'),
port: configService.get<number>('REDIS_PORT'),
password: configService.get<string>('REDIS_PASSWORD'), // Если требуется
},
},
}),
}),
],
// ...
})
export class AppModule {}
// В вашем сервисе (например, product.service.ts)
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Product } from './product.entity';
@Injectable()
export class ProductService {
constructor(
@InjectRepository(Product)
private readonly productRepository: Repository<Product>,
) {}
async findAll() {
// Этот запрос будет закэширован в Redis на указанное в конфиге время
return this.productRepository.find({
cache: true,
});
}
async findOne(id: number) {
// Или с определенным ключом и временем жизни
return this.productRepository.findOne({
where: { id },
cache: {
id: `product-cache-${id}`,
milliseconds: 30000 // 30 секунд
},
});
}
}
import {
WebSocketGateway,
SubscribeMessage,
MessageBody,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { RedisService } from '../redis/redis.service';
import { Logger } from '@nestjs/common';
@WebSocketGateway({
cors: {
origin: '*', // Настройте CORS под ваш Angular-клиент
},
})
export class StatusGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server;
private readonly logger = new Logger(StatusGateway.name);
constructor(private readonly redisService: RedisService) {}
// Этот метод вызывается при подключении нового пользователя
async handleConnection(client: Socket) {
// В реальном приложении здесь вы бы аутентифицировали клиента по токену/кукам
// и получили его реальный userId.
const userId = client.handshake.query.userId as string;
if (userId) {
await this.redisService.setUserOnline(userId);
this.logger.log(`User ${userId} connected.`);
// Отправляем всем друзьям (или всем подключенным клиентам) уведомление об изменении статуса
this.server.emit('friendStatusChanged', { userId, status: 'online' });
}
}
// Этот метод вызывается при отключении пользователя
async handleDisconnect(client: Socket) {
const userId = client.handshake.query.userId as string;
if (userId) {
await this.redisService.setUserOffline(userId);
this.logger.log(`User ${userId} disconnected.`);
// Отправляем всем друзьям уведомление об изменении статуса
this.server.emit('friendStatusChanged', { userId, status: 'offline' });
}
}
// Пример обработки пользовательского сообщения (опционально)
@SubscribeMessage('sendMessage')
handleMessage(@ConnectedSocket() client: Socket, @MessageBody() payload: any): void {
// Обработка сообщений и возможное сохранение через TypeORM
this.server.emit('receiveMessage', payload);
}
}