feat: 实现实时匿名会话

This commit is contained in:
root
2026-09-16 09:55:03 +08:00
parent 11fcdb5307
commit 13b8b9ded8
14 changed files with 2042 additions and 31 deletions
@@ -0,0 +1,22 @@
import { Inject, Injectable } from "@nestjs/common";
import { RedisService } from "../redis/redis.service.js";
@Injectable()
export class ChatRateLimiter {
constructor(@Inject(RedisService) private readonly redis: RedisService) {}
async consume(accountId: string, sessionId: string): Promise<boolean> {
await this.redis.ensureConnected();
const prefix = process.env.REDIS_KEY_PREFIX ?? "drift:auth:";
const max = Number(process.env.CHAT_MESSAGE_RATE_LIMIT ?? 30);
const ttl = Number(process.env.CHAT_MESSAGE_RATE_WINDOW_SECONDS ?? 60);
const keys = [
`${prefix}chat:account:${accountId}`,
`${prefix}chat:session:${sessionId}`,
];
const result = await this.redis.client.eval(
`for _,k in ipairs(KEYS) do if tonumber(redis.call('GET',k) or '0')+1>tonumber(ARGV[1]) then return 0 end end; for _,k in ipairs(KEYS) do local n=redis.call('INCR',k); if n==1 then redis.call('EXPIRE',k,ARGV[2]) end end; return 1`,
{ keys, arguments: [String(max), String(ttl)] },
);
return Number(result) === 1;
}
}