dynamic-interaction
Version:
Dynamic interaction 动态交互mcp,用于cursor、windsurf、trae 等 AI 智能编辑器 Agent 运行时交互使用
186 lines (185 loc) • 6.8 kB
JavaScript
;
/**
* 会话管理器
* 重构和改进的会话管理功能
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.sessionManager = exports.SessionManager = void 0;
const logger_1 = require("../../logger");
const context_1 = require("./context");
const queue_1 = require("./queue");
const transport_1 = require("../websocket/transport");
const config_1 = require("../../config");
const errors_1 = require("../utils/errors");
class SessionManager {
static instance;
activeSessions = new Map();
sessionById = new Map();
constructor() { }
static getInstance() {
if (!SessionManager.instance) {
SessionManager.instance = new SessionManager();
}
return SessionManager.instance;
}
createSession(ws, request) {
if (this.activeSessions.has(ws)) {
const existing = this.activeSessions.get(ws);
logger_1.logger.warn(`WebSocket连接已存在会话,ID: ${existing.id}`);
return existing;
}
const timeout = parseInt(process.env.SESSION_TIMEOUT || '300', 10);
const session = new context_1.SessionContextBuilder()
.setId(request.id)
.setWebSocket(ws)
.setRequest(request)
.setStartTime(request.createdAt)
.setTimeout(timeout)
.setMode(request.mode)
.build();
// 设置超时处理
session.timeoutId = setTimeout(() => {
this.handleTimeout(session);
}, config_1.SESSION_TIMEOUT * 1000);
// 存储会话
this.activeSessions.set(ws, session);
this.sessionById.set(session.id, session);
logger_1.logger.info(`会话已创建,ID: ${session.id},模式: ${session.mode},活跃会话数: ${this.activeSessions.size}`);
// 发送会话初始化信息
this.initializeSession(session);
return session;
}
initializeSession(session) {
// 发送摘要信息
transport_1.transport.send(session.ws, {
type: 'summary',
data: session.request.summary
});
// 发送系统信息
transport_1.transport.sendSystemInfo(session.ws, session.id, session.request.projectDirectory || process.cwd(), session.startTime, session.timeout, session.mode);
}
endSession(ws) {
const session = this.activeSessions.get(ws);
if (!session) {
logger_1.logger.warn('尝试结束不存在的会话');
return;
}
this.cleanup(session);
logger_1.logger.info(`会话已结束,ID: ${session.id},剩余活跃会话: ${this.activeSessions.size}`);
}
endSessionById(sessionId) {
const session = this.sessionById.get(sessionId);
if (!session) {
logger_1.logger.warn(`尝试结束不存在的会话,ID: ${sessionId}`);
return;
}
this.cleanup(session);
}
cleanup(session) {
// 清理超时定时器
if (session.timeoutId) {
clearTimeout(session.timeoutId);
session.timeoutId = null;
}
// 从映射中移除
this.activeSessions.delete(session.ws);
this.sessionById.delete(session.id);
}
handleTimeout(session) {
logger_1.logger.warn(`会话超时,ID: ${session.id}`);
// 发送超时通知
transport_1.transport.send(session.ws, {
type: 'timeout',
data: { message: '会话因长时间未活动已超时' }
});
transport_1.transport.send(session.ws, {
type: 'stop_timer'
});
// 解析会话Promise,返回超时标识
session.request.resolve({
text: '__SESSION_TIMEOUT__',
imageData: []
});
// 确认队列中的请求
queue_1.sessionQueue.acknowledge(session.request.id);
// 清理会话
this.cleanup(session);
}
handleDisconnection(ws) {
const session = this.activeSessions.get(ws);
if (!session) {
return;
}
logger_1.logger.info(`客户端断开连接,会话ID: ${session.id}`);
// 将请求重新入队
queue_1.sessionQueue.requeue(session.request.id, new Error('WebSocket连接在反馈完成前关闭'));
// 清理会话
this.cleanup(session);
// 通知生命周期管理器检查空闲状态
const { lifecycleManager } = require('../core/lifecycle');
lifecycleManager.checkAndStopIfIdle();
}
getSessionByWs(ws) {
return this.activeSessions.get(ws);
}
getSessionById(sessionId) {
return this.sessionById.get(sessionId);
}
hasSession(ws) {
return this.activeSessions.has(ws);
}
getSessionCount() {
return this.activeSessions.size;
}
getSessionStats(sessionId) {
const session = this.sessionById.get(sessionId);
if (!session) {
return null;
}
const now = Date.now();
const elapsedTime = now - session.startTime;
const remainingTime = Math.max(0, (session.timeout * 1000) - elapsedTime);
return {
id: session.id,
startTime: session.startTime,
elapsedTime,
remainingTime: Math.floor(remainingTime / 1000),
mode: session.mode,
projectDirectory: session.request.projectDirectory
};
}
getAllSessions() {
return Array.from(this.activeSessions.values());
}
clearAll() {
logger_1.logger.info(`清理所有会话 (${this.activeSessions.size}个)`);
for (const session of this.activeSessions.values()) {
// 清理超时定时器
if (session.timeoutId) {
clearTimeout(session.timeoutId);
}
// 拒绝未完成的请求
session.request.reject(new errors_1.SessionError('服务器正在关闭', errors_1.ErrorCodes.SERVER_STOP_ERROR));
}
this.activeSessions.clear();
this.sessionById.clear();
}
extendSession(sessionId, additionalTime) {
const session = this.sessionById.get(sessionId);
if (!session) {
return false;
}
// 清除当前超时定时器
if (session.timeoutId) {
clearTimeout(session.timeoutId);
}
// 设置新的超时定时器
session.timeoutId = setTimeout(() => {
this.handleTimeout(session);
}, additionalTime * 1000);
logger_1.logger.info(`会话时间已延长,ID: ${sessionId},延长时间: ${additionalTime}秒`);
return true;
}
}
exports.SessionManager = SessionManager;
exports.sessionManager = SessionManager.getInstance();