// src/main/redis/connection.ts // Redis 连接管理 import Redis, { RedisOptions } from 'ioredis' import type { ConnectionOptions } from '../../shared/types' export type RedisClient = Redis const clients = new Map() function buildRedisOptions(opts: ConnectionOptions): RedisOptions { const options: RedisOptions = { host: opts.host, port: opts.port, username: opts.username || undefined, password: opts.password || undefined, stringNumbers: true, enableReadyCheck: true, family: 0, connectTimeout: 10000, retryStrategy(times: number) { if (times > 3) return null return Math.min(times * 200, 1000) }, maxRetriesPerRequest: 3, } if (opts.tls) { options.tls = { rejectUnauthorized: false, checkServerIdentity: () => undefined, } } return options } export function getClient(id: string): RedisClient | undefined { return clients.get(id) } export function isClientConnected(id: string): boolean { const client = clients.get(id) return client?.status === 'ready' } export async function connect(id: string, opts: ConnectionOptions): Promise { if (clients.has(id)) { await disconnect(id) } return new Promise((resolve, reject) => { const redis = new Redis(buildRedisOptions(opts)) redis.once('ready', () => { clients.set(id, redis) resolve() }) redis.once('error', (err: Error) => { redis.disconnect() reject(err) }) setTimeout(() => { if (!clients.has(id)) { redis.disconnect() reject(new Error('连接超时,请检查主机和端口')) } }, 12000) }) } export async function disconnect(id: string): Promise { const client = clients.get(id) if (client) { client.disconnect() clients.delete(id) } } export function disconnectAll(): void { for (const [id] of clients) { disconnect(id) } }