Files
makemd/node-agent/src/enhanced-client.ts
wurenzhi 22308fe042 refactor: 重构项目结构并优化代码
- 删除无用的文件和错误日志
- 创建统一的 imports 模块集中管理依赖
- 重构组件使用新的 imports 方式
- 修复文档路径大小写问题
- 优化类型定义和接口导出
- 更新依赖版本
- 改进错误处理和API配置
- 统一组件导出方式
2026-03-27 16:56:06 +08:00

564 lines
14 KiB
TypeScript

/**
* 增强版轻量级客户端 - 集成所有功能
* 支持模拟API、自动化任务、定时操作等完整功能
*/
import { WebSocketServer, WebSocket } from 'ws';
import { createServer } from 'http';
import * as os from 'os';
import { ApiSimulator, LoginCredentials, ApiRequest } from './api-simulator';
import { PlatformManager, PlatformAdapter } from './platform-adapter';
import { TaskScheduler, TaskConfig, WorkflowConfig } from './task-scheduler';
export interface EnhancedClientConfig {
port: number;
headless: boolean;
proxy?: string;
userDataDir: string;
}
interface EnhancedCommand {
type: 'login' | 'api' | 'task' | 'workflow' | 'status' | 'control';
platform?: string;
action: string;
data: any;
}
interface EnhancedResponse {
success: boolean;
type: string;
data?: any;
error?: string;
timestamp: number;
}
/**
* 增强版轻量级客户端
*/
export class EnhancedClient {
private config: EnhancedClientConfig;
private wss: WebSocketServer;
private apiSimulator: ApiSimulator;
private platformManager: PlatformManager;
private taskScheduler: TaskScheduler;
private connectedClients: Set<WebSocket> = new Set();
constructor(config: EnhancedClientConfig) {
this.config = config;
// 初始化核心组件
this.apiSimulator = new ApiSimulator({
headless: config.headless,
proxy: config.proxy,
userDataDir: config.userDataDir,
timeout: 30000
});
this.platformManager = new PlatformManager(this.apiSimulator);
this.taskScheduler = new TaskScheduler(this.platformManager);
// 创建HTTP服务器用于健康检查和API接口
const server = createServer((req, res) => {
this.handleHttpRequest(req, res);
});
// 创建WebSocket服务器
this.wss = new WebSocketServer({ server });
server.listen(config.port);
this.setupWebSocketHandlers();
this.initializeComponents();
}
/**
* 初始化组件
*/
private async initializeComponents(): Promise<void> {
try {
await this.apiSimulator.initialize();
console.log('API模拟器初始化完成');
// 加载已保存的登录状态
await this.loadSavedLoginStates();
console.log('增强版客户端初始化完成');
} catch (error) {
console.error('客户端初始化失败:', error);
}
}
/**
* 加载已保存的登录状态
*/
private async loadSavedLoginStates(): Promise<void> {
// 这里可以加载之前保存的登录状态
console.log('加载已保存的登录状态...');
}
/**
* 处理HTTP请求
*/
private handleHttpRequest(req: any, res: any): void {
const { url, method } = req;
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
if (url === '/health') {
res.writeHead(200);
res.end(JSON.stringify(this.getHealthStatus()));
} else if (url === '/status' && method === 'GET') {
res.writeHead(200);
res.end(JSON.stringify(this.getClientStatus()));
} else if (url === '/tasks' && method === 'GET') {
res.writeHead(200);
res.end(JSON.stringify(this.taskScheduler.getTasks()));
} else if (url === '/platforms' && method === 'GET') {
res.writeHead(200);
res.end(JSON.stringify({
supported: this.platformManager.getSupportedPlatforms(),
loggedIn: this.platformManager.getLoggedInPlatforms()
}));
} else {
res.writeHead(404);
res.end(JSON.stringify({ error: '接口不存在' }));
}
}
/**
* 设置WebSocket处理器
*/
private setupWebSocketHandlers(): void {
this.wss.on('connection', (ws: WebSocket) => {
console.log('客户端连接建立');
this.connectedClients.add(ws);
// 发送连接成功消息
ws.send(JSON.stringify({
type: 'connection',
success: true,
message: '连接成功',
timestamp: Date.now()
}));
ws.on('message', async (data: Buffer) => {
try {
const command: EnhancedCommand = JSON.parse(data.toString());
const response = await this.handleEnhancedCommand(command);
ws.send(JSON.stringify(response));
} catch (error) {
ws.send(JSON.stringify({
type: 'error',
success: false,
error: error instanceof Error ? error.message : '命令处理失败',
timestamp: Date.now()
}));
}
});
ws.on('close', () => {
console.log('客户端连接关闭');
this.connectedClients.delete(ws);
});
ws.on('error', (error) => {
console.error('WebSocket错误:', error);
this.connectedClients.delete(ws);
});
});
}
/**
* 处理增强命令
*/
private async handleEnhancedCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
try {
switch (command.type) {
case 'login':
return await this.handleLoginCommand(command);
case 'api':
return await this.handleApiCommand(command);
case 'task':
return await this.handleTaskCommand(command);
case 'workflow':
return await this.handleWorkflowCommand(command);
case 'status':
return await this.handleStatusCommand(command);
case 'control':
return await this.handleControlCommand(command);
default:
return {
type: 'error',
success: false,
error: '未知命令类型',
timestamp: Date.now()
};
}
} catch (error) {
return {
type: 'error',
success: false,
error: error instanceof Error ? error.message : '命令执行失败',
timestamp: Date.now()
};
}
}
/**
* 处理登录命令
*/
private async handleLoginCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { platform, username, password } = command.data;
if (!platform || !username || !password) {
return {
type: 'login',
success: false,
error: '缺少必要的登录参数',
timestamp: Date.now()
};
}
const credentials: LoginCredentials = {
platform,
username,
password
};
const result = await this.apiSimulator.login(credentials);
return {
type: 'login',
success: result.success,
data: result.data,
error: result.error,
timestamp: Date.now()
};
}
/**
* 处理API命令
*/
private async handleApiCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { platform, endpoint, method, params } = command.data;
if (!platform || !endpoint) {
return {
type: 'api',
success: false,
error: '缺少必要的API参数',
timestamp: Date.now()
};
}
const apiRequest: ApiRequest = {
platform,
endpoint,
method: method || 'GET',
params: params || {}
};
const result = await this.apiSimulator.simulateApiCall(apiRequest);
return {
type: 'api',
success: result.success,
data: result.data,
error: result.error,
timestamp: Date.now()
};
}
/**
* 处理任务命令
*/
private async handleTaskCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { action, data } = command;
switch (action) {
case 'list':
return {
type: 'task',
success: true,
data: this.taskScheduler.getTasks(),
timestamp: Date.now()
};
case 'add':
this.taskScheduler.addTask(data as TaskConfig);
return {
type: 'task',
success: true,
data: { message: '任务添加成功' },
timestamp: Date.now()
};
case 'execute':
const execution = await this.taskScheduler.executeTask(data.taskId, true);
return {
type: 'task',
success: execution.status === 'completed',
data: execution,
timestamp: Date.now()
};
case 'enable':
this.taskScheduler.setTaskEnabled(data.taskId, true);
return {
type: 'task',
success: true,
data: { message: '任务已启用' },
timestamp: Date.now()
};
case 'disable':
this.taskScheduler.setTaskEnabled(data.taskId, false);
return {
type: 'task',
success: true,
data: { message: '任务已禁用' },
timestamp: Date.now()
};
default:
return {
type: 'task',
success: false,
error: '未知的任务操作',
timestamp: Date.now()
};
}
}
/**
* 处理工作流命令
*/
private async handleWorkflowCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { action, data } = command;
switch (action) {
case 'add':
this.taskScheduler.addWorkflow(data as WorkflowConfig);
return {
type: 'workflow',
success: true,
data: { message: '工作流添加成功' },
timestamp: Date.now()
};
default:
return {
type: 'workflow',
success: false,
error: '未知的工作流操作',
timestamp: Date.now()
};
}
}
/**
* 处理状态命令
*/
private async handleStatusCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { action } = command;
switch (action) {
case 'overview':
return {
type: 'status',
success: true,
data: this.getClientStatus(),
timestamp: Date.now()
};
case 'platforms':
return {
type: 'status',
success: true,
data: {
supported: this.platformManager.getSupportedPlatforms(),
loggedIn: this.platformManager.getLoggedInPlatforms()
},
timestamp: Date.now()
};
case 'tasks':
return {
type: 'status',
success: true,
data: {
tasks: this.taskScheduler.getTasks(),
history: Array.from(this.taskScheduler.getAllHistory().entries())
},
timestamp: Date.now()
};
default:
return {
type: 'status',
success: false,
error: '未知的状态操作',
timestamp: Date.now()
};
}
}
/**
* 处理控制命令
*/
private async handleControlCommand(command: EnhancedCommand): Promise<EnhancedResponse> {
const { action } = command;
switch (action) {
case 'restart':
// 重启客户端逻辑
return {
type: 'control',
success: true,
data: { message: '客户端重启中...' },
timestamp: Date.now()
};
case 'stop':
// 停止客户端逻辑
return {
type: 'control',
success: true,
data: { message: '客户端停止中...' },
timestamp: Date.now()
};
default:
return {
type: 'control',
success: false,
error: '未知的控制操作',
timestamp: Date.now()
};
}
}
/**
* 获取健康状态
*/
private getHealthStatus(): any {
return {
status: 'healthy',
platform: os.platform(),
version: '2.0.0',
uptime: process.uptime(),
memory: process.memoryUsage(),
connectedClients: this.connectedClients.size,
timestamp: Date.now()
};
}
/**
* 获取客户端状态
*/
private getClientStatus(): any {
return {
platform: os.platform(),
version: '2.0.0',
uptime: process.uptime(),
// 平台状态
platforms: {
supported: this.platformManager.getSupportedPlatforms(),
loggedIn: this.platformManager.getLoggedInPlatforms(),
total: this.platformManager.getSupportedPlatforms().length
},
// 任务状态
tasks: {
total: this.taskScheduler.getTasks().length,
enabled: this.taskScheduler.getTasks().filter(t => t.enabled).length,
disabled: this.taskScheduler.getTasks().filter(t => !t.enabled).length
},
// 连接状态
connections: {
webSocket: this.connectedClients.size,
http: 'active'
},
timestamp: Date.now()
};
}
/**
* 广播消息给所有连接的客户端
*/
private broadcastMessage(message: any): void {
const messageStr = JSON.stringify(message);
this.connectedClients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(messageStr);
}
});
}
/**
* 启动客户端
*/
async start(): Promise<void> {
console.log(`增强版客户端启动在端口 ${this.config.port}`);
console.log(`健康检查: http://localhost:${this.config.port}/health`);
console.log(`状态查询: http://localhost:${this.config.port}/status`);
console.log('等待前端连接...');
// 启动定时状态报告
setInterval(() => {
this.broadcastMessage({
type: 'heartbeat',
data: this.getClientStatus(),
timestamp: Date.now()
});
}, 30000); // 每30秒发送一次心跳
}
/**
* 停止客户端
*/
async stop(): Promise<void> {
// 停止所有任务
this.taskScheduler.stopAllTasks();
// 关闭浏览器实例
await this.apiSimulator.close();
// 关闭WebSocket服务器
this.wss.close();
console.log('增强版客户端已停止');
}
}
// 命令行启动
if (require.main === module) {
const config: EnhancedClientConfig = {
port: process.env.PORT ? parseInt(process.env.PORT) : 8080,
headless: process.env.HEADLESS !== 'false',
proxy: process.env.PROXY || undefined,
userDataDir: process.env.USER_DATA_DIR || './user-data'
};
const client = new EnhancedClient(config);
client.start();
// 优雅关闭
process.on('SIGINT', async () => {
console.log('收到关闭信号,正在停止客户端...');
await client.stop();
process.exit(0);
});
}