import Connect from 'connect' import { ServerResponse } from 'node:http'; import { parse } from 'cookie' interface Massage { type: string; value: string; time: number; } let sessionList: {[session: string]: Set>} = {} export default async function SseMid(req: Connect.IncomingMessage, res: ServerResponse, next: Connect.NextFunction) { const BaseUrl = process.env.BASE_URL // 检查session_id let session_id: string | undefined = undefined const cookies = parse(req.headers.cookie ?? '') if (!cookies.session_id) { session_id = crypto.randomUUID() res.setHeader('Set-Cookie', `session_id=${session_id}; HttpOnly; Path=/`) } else { session_id = cookies.session_id } // 处理SSE if (req.url === BaseUrl + 'sse') { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }) const interval = setInterval(() => { const msg = { type: 'pending', value: session_id, time: Date.now() } res.write(`data: ${JSON.stringify(msg)}\n\n`) }, 60 * 1000) req.on('close', () => { clearInterval(interval) res.end() if (sessionList[session_id]) { sessionList[session_id].delete(res) } }) // 插入res if (!sessionList[session_id]) { sessionList[session_id] = new Set> } sessionList[session_id].add(res) return } // 继续执行下一个中间件 next(); } export function sendReLogin(session_id: string): boolean { if (!sessionList[session_id]) return false console.log("send relogin: ", session_id) sessionList[session_id].forEach(res => { const msg: Massage = { type: 'command', value: 'Re-login', time: Date.now() } res.write(`data: ${JSON.stringify(msg)}\n\n`) }); return true }