- 添加PDMS软件配置,支持批处理文件启动方式 - 配置executable_path为pdms.bat,startup_args为["Design", "noconsole"] - 通过进程检测工具确定正确的进程名称:des.exe和PDMSConsole.exe - 新增check_pdms_processes.py进程检测工具,可自动识别PDMS进程 - 更新Readme.md和frontend-api-docs.md文档 - 支持与Creo、Revit一致的启动、停止、重启功能 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
857 lines
23 KiB
Markdown
857 lines
23 KiB
Markdown
# CadHubManage 前端API文档
|
||
|
||
## 项目概述
|
||
CadHubManage是一个通过WebSocket实时控制Windows服务器上软件的管理系统,提供软件启动、停止、状态监控和操作日志记录功能。
|
||
|
||
## 基础信息
|
||
- **API版本**: v1.0.0
|
||
- **WebSocket URL**: `ws://localhost:8000/api/v1/ws/connect`
|
||
- **协议**: WebSocket
|
||
- **数据格式**: JSON
|
||
|
||
## 快速开始
|
||
|
||
### 1. 健康检查(HTTP接口)
|
||
```http
|
||
GET /health
|
||
```
|
||
响应:
|
||
```json
|
||
{
|
||
"status": "healthy"
|
||
}
|
||
```
|
||
|
||
### 2. 服务信息(HTTP接口)
|
||
```http
|
||
GET /
|
||
```
|
||
响应:
|
||
```json
|
||
{
|
||
"message": "CadHubManage API服务正在运行",
|
||
"version": "1.0.0",
|
||
"docs": "/docs"
|
||
}
|
||
```
|
||
|
||
### 3. 连接WebSocket
|
||
```javascript
|
||
const ws = new WebSocket('ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin');
|
||
```
|
||
|
||
## WebSocket实时通信API
|
||
|
||
### 连接WebSocket
|
||
```
|
||
ws://localhost:8000/api/v1/ws/connect?client_id=client123&user_id=user456
|
||
```
|
||
|
||
**连接参数:**
|
||
- `client_id`: 客户端唯一标识符 (可选,自动生成)
|
||
- `user_id`: 用户ID (可选)
|
||
|
||
### WebSocket消息格式
|
||
|
||
#### 发送消息类型
|
||
|
||
**1. 心跳检测**
|
||
```json
|
||
{
|
||
"type": "ping" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "ping"
|
||
|
||
**2. 获取服务状态**
|
||
```json
|
||
{
|
||
"type": "get_status" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "get_status"
|
||
|
||
**3. 获取软件列表**
|
||
```json
|
||
{
|
||
"type": "get_software_list" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "get_software_list"
|
||
|
||
**4. 启动软件**
|
||
```json
|
||
{
|
||
"type": "start_software", // 必填:固定值
|
||
"software_id": "creo" // 必填:软件标识符
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "start_software"
|
||
- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线
|
||
|
||
**5. 停止软件**
|
||
```json
|
||
{
|
||
"type": "stop_software", // 必填:固定值
|
||
"software_id": "creo" // 必填:软件标识符
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "stop_software"
|
||
- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线
|
||
|
||
**6. 重启软件**
|
||
```json
|
||
{
|
||
"type": "restart_software", // 必填:固定值
|
||
"software_id": "creo" // 必填:软件标识符
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "restart_software"
|
||
- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线
|
||
|
||
**6. 记录操作日志**
|
||
```json
|
||
{
|
||
"type": "log_operation", // 必填:固定值
|
||
"operation": "手动启动软件", // 必填:操作名称
|
||
"details": "用户通过界面启动Creo", // 可选:详细描述
|
||
"action_type": "software_control", // 可选:行为类型
|
||
"target_object": "creo", // 可选:目标对象
|
||
"status": "success", // 可选:操作状态
|
||
"duration": 5.2, // 可选:操作耗时(秒)
|
||
"operation_category": "软件控制" // 可选:操作分类
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "log_operation"
|
||
- `operation` (必填,string): 操作名称,长度1-100字符
|
||
- `details` (可选,string): 详细描述,最大1000字符
|
||
- `action_type` (可选,string): 行为类型,可选值: create, read, update, delete, execute, export, import
|
||
- `target_object` (可选,string): 目标对象,最大50字符
|
||
- `status` (可选,string): 操作状态,可选值: success, failed, pending,默认success
|
||
- `duration` (可选,number): 操作耗时,单位秒,范围0-3600
|
||
- `operation_category` (可选,string): 操作分类,最大50字符
|
||
|
||
**7. 查询操作日志**
|
||
```json
|
||
{
|
||
"type": "query_logs", // 必填:固定值
|
||
"log_type": "user_operation", // 可选:日志类型
|
||
"operation": "启动软件", // 可选:操作名称
|
||
"user_id_filter": "user123", // 可选:用户ID过滤
|
||
"level": "info", // 可选:日志级别
|
||
"start_time": "2024-01-01T00:00:00Z", // 可选:开始时间
|
||
"end_time": "2024-01-02T00:00:00Z", // 可选:结束时间
|
||
"limit": 100, // 可选:返回数量限制
|
||
"offset": 0 // 可选:偏移量
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "query_logs"
|
||
- `log_type` (可选,string): 日志类型,可选值: system_operation, user_operation
|
||
- `operation` (可选,string): 操作名称,支持模糊匹配
|
||
- `user_id_filter` (可选,string): 用户ID过滤,最大50字符
|
||
- `level` (可选,string): 日志级别,可选值: debug, info, warning, error
|
||
- `start_time` (可选,string): 开始时间,ISO 8601格式 (YYYY-MM-DDTHH:mm:ssZ)
|
||
- `end_time` (可选,string): 结束时间,ISO 8601格式 (YYYY-MM-DDTHH:mm:ssZ)
|
||
- `limit` (可选,number): 返回数量限制,范围1-1000,默认100
|
||
- `offset` (可选,number): 偏移量,最小0,默认0
|
||
|
||
**8. 根据ID获取日志**
|
||
```json
|
||
{
|
||
"type": "get_log_by_id", // 必填:固定值
|
||
"log_id": "log_123" // 必填:日志ID
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "get_log_by_id"
|
||
- `log_id` (必填,string): 日志唯一标识符,长度1-100字符
|
||
|
||
**9. 获取日志统计信息**
|
||
```json
|
||
{
|
||
"type": "get_log_stats" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "get_log_stats"
|
||
|
||
**10. 清理过期日志**
|
||
```json
|
||
{
|
||
"type": "cleanup_logs" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "cleanup_logs"
|
||
|
||
**11. 获取操作类型列表**
|
||
```json
|
||
{
|
||
"type": "get_operation_types" // 必填:固定值
|
||
}
|
||
```
|
||
**参数说明:**
|
||
- `type` (必填,string): 固定值 "get_operation_types"
|
||
|
||
#### 接收消息类型
|
||
|
||
**1. 欢迎消息**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "欢迎连接!客户端ID: client123",
|
||
"client_id": "client123",
|
||
"user_id": "user456",
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**2. 心跳响应**
|
||
```json
|
||
{
|
||
"type": "heartbeat",
|
||
"message": "pong",
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**3. 服务状态响应**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "服务状态正常",
|
||
"data": {
|
||
"active_connections": 3,
|
||
"connected_users": ["user123", "user456"]
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**4. 软件列表更新**
|
||
```json
|
||
{
|
||
"type": "software_list_update",
|
||
"data": {
|
||
"software_list": [
|
||
{
|
||
"id": "creo",
|
||
"name": "PTC Creo",
|
||
"status": "running",
|
||
"executable_path": "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe"
|
||
}
|
||
]
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**5. 任务创建响应**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "软件 creo 启动任务已创建",
|
||
"data": {
|
||
"task_id": "task_123",
|
||
"software_id": "creo",
|
||
"status": "pending"
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**6. 日志记录确认**
|
||
```json
|
||
{
|
||
"type": "log_recorded",
|
||
"message": "操作日志已记录",
|
||
"data": {
|
||
"log_id": "log_456",
|
||
"operation": "手动启动软件"
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**7. 日志查询响应**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "日志查询成功",
|
||
"data": {
|
||
"logs": [
|
||
{
|
||
"id": "log_123",
|
||
"operation": "启动软件",
|
||
"user_id": "user123",
|
||
"timestamp": "2024-01-01T10:00:00Z",
|
||
"level": "info",
|
||
"details": "启动PTC Creo成功"
|
||
}
|
||
],
|
||
"total": 1,
|
||
"limit": 100,
|
||
"offset": 0
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**8. 日志统计响应**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "获取统计信息成功",
|
||
"data": {
|
||
"stats": {
|
||
"period": "24小时",
|
||
"system_operations": 45,
|
||
"user_operations": 123,
|
||
"error_logs": 2,
|
||
"total_logs": 168,
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**9. 操作类型列表响应**
|
||
```json
|
||
{
|
||
"type": "info",
|
||
"message": "获取操作类型成功",
|
||
"data": {
|
||
"operations": ["启动软件", "停止软件", "重启软件"],
|
||
"categories": ["软件控制", "系统管理"],
|
||
"total_operations": 3,
|
||
"total_categories": 2
|
||
},
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
**10. 错误消息**
|
||
```json
|
||
{
|
||
"type": "error",
|
||
"message": "启动软件失败: 软件路径不存在",
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
## 数据模型
|
||
|
||
### 软件配置
|
||
当前支持的软件(位于`configs/software_config.yaml`):
|
||
```yaml
|
||
software:
|
||
creo:
|
||
name: "PTC Creo"
|
||
executable_path: "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe"
|
||
startup_args: []
|
||
startup_timeout: 60
|
||
check_process_name: ["xtop.exe", "pro_comm_msg.exe"] # 支持多进程检测
|
||
stop_timeout: 15 # 停止超时时间(秒)
|
||
|
||
revit:
|
||
name: "Autodesk Revit 2017"
|
||
executable_path: "C:\\Program Files\\Autodesk\\Revit 2017\\Revit.exe"
|
||
startup_args: ["/language", "CHS"]
|
||
startup_timeout: 90
|
||
check_process_name: "Revit.exe" # 单进程检测
|
||
|
||
pdms:
|
||
name: "AVEVA PDMS 12.1 SP4"
|
||
executable_path: "C:\\AVEVA\\Plant\\PDMS12.1.SP4\\pdms.bat" # 支持批处理文件
|
||
startup_args: ["Design", "noconsole"]
|
||
startup_timeout: 120
|
||
check_process_name: ["des.exe", "PDMSConsole.exe"] # PDMS多进程检测
|
||
stop_timeout: 20
|
||
```
|
||
|
||
**配置字段说明:**
|
||
- `name`: 软件显示名称
|
||
- `executable_path`: 软件可执行文件完整路径
|
||
- `startup_args`: 启动参数数组
|
||
- `startup_timeout`: 启动超时时间(秒)
|
||
- `check_process_name`: 进程检测名称,支持字符串(单进程)或数组(多进程)
|
||
- `stop_timeout`: 停止操作超时时间(秒),可选
|
||
|
||
### 日志类型枚举
|
||
- **LogType**: `system_operation`, `user_operation`
|
||
- **LogLevel**: `debug`, `info`, `warning`, `error`
|
||
- **ActionType**: `create`, `read`, `update`, `delete`, `execute`, `export`, `import`
|
||
- **OperationStatus**: `success`, `failed`, `pending`
|
||
|
||
## 错误处理
|
||
|
||
### HTTP错误码
|
||
- `200`: 成功
|
||
- `404`: 资源不存在
|
||
- `500`: 服务器内部错误
|
||
|
||
### WebSocket错误
|
||
错误消息统一格式:
|
||
```json
|
||
{
|
||
"type": "error",
|
||
"message": "错误描述",
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### JavaScript WebSocket客户端示例
|
||
```javascript
|
||
// 连接WebSocket
|
||
const ws = new WebSocket('ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin');
|
||
|
||
// 连接成功
|
||
ws.onopen = function() {
|
||
console.log('WebSocket连接成功');
|
||
|
||
// 发送心跳
|
||
ws.send(JSON.stringify({type: 'ping'}));
|
||
};
|
||
|
||
// 接收消息
|
||
ws.onmessage = function(event) {
|
||
const message = JSON.parse(event.data);
|
||
console.log('收到消息:', message);
|
||
|
||
switch(message.type) {
|
||
case 'heartbeat':
|
||
console.log('心跳响应');
|
||
break;
|
||
case 'software_list_update':
|
||
console.log('软件列表:', message.data.software_list);
|
||
break;
|
||
case 'info':
|
||
if (message.data && message.data.logs) {
|
||
console.log('日志查询结果:', message.data.logs);
|
||
} else if (message.data && message.data.stats) {
|
||
console.log('统计信息:', message.data.stats);
|
||
}
|
||
break;
|
||
case 'error':
|
||
console.error('错误:', message.message);
|
||
break;
|
||
}
|
||
};
|
||
|
||
// 启动软件
|
||
function startSoftware(softwareId) {
|
||
ws.send(JSON.stringify({
|
||
type: 'start_software',
|
||
software_id: softwareId
|
||
}));
|
||
}
|
||
|
||
// 停止软件
|
||
function stopSoftware(softwareId) {
|
||
ws.send(JSON.stringify({
|
||
type: 'stop_software',
|
||
software_id: softwareId
|
||
}));
|
||
}
|
||
|
||
// 重启软件
|
||
function restartSoftware(softwareId) {
|
||
ws.send(JSON.stringify({
|
||
type: 'restart_software',
|
||
software_id: softwareId
|
||
}));
|
||
}
|
||
|
||
// 记录操作日志
|
||
function logOperation(operation, details) {
|
||
ws.send(JSON.stringify({
|
||
type: 'log_operation',
|
||
operation: operation,
|
||
details: details,
|
||
status: 'success'
|
||
}));
|
||
}
|
||
|
||
// 查询日志
|
||
function queryLogs(filters = {}) {
|
||
ws.send(JSON.stringify({
|
||
type: 'query_logs',
|
||
...filters
|
||
}));
|
||
}
|
||
|
||
// 获取日志统计
|
||
function getLogStats() {
|
||
ws.send(JSON.stringify({
|
||
type: 'get_log_stats'
|
||
}));
|
||
}
|
||
|
||
// 获取操作类型列表
|
||
function getOperationTypes() {
|
||
ws.send(JSON.stringify({
|
||
type: 'get_operation_types'
|
||
}));
|
||
}
|
||
|
||
// 清理过期日志
|
||
function cleanupLogs() {
|
||
ws.send(JSON.stringify({
|
||
type: 'cleanup_logs'
|
||
}));
|
||
}
|
||
|
||
// 使用示例
|
||
setTimeout(() => {
|
||
// 查询最近的用户操作日志
|
||
queryLogs({
|
||
log_type: 'user_operation',
|
||
limit: 50,
|
||
offset: 0
|
||
});
|
||
|
||
// 获取统计信息
|
||
getLogStats();
|
||
|
||
// 获取操作类型
|
||
getOperationTypes();
|
||
}, 1000);
|
||
```
|
||
|
||
## WebSocket连接管理指南
|
||
|
||
### 连接状态管理
|
||
|
||
WebSocket连接具有多种状态,前端需要正确处理这些状态转换:
|
||
|
||
```javascript
|
||
class WebSocketManager {
|
||
constructor(url, options = {}) {
|
||
this.url = url;
|
||
this.ws = null;
|
||
this.connectionState = 'DISCONNECTED'; // CONNECTING, CONNECTED, DISCONNECTED, ERROR
|
||
this.reconnectAttempts = 0;
|
||
this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
|
||
this.reconnectDelay = options.reconnectDelay || 1000;
|
||
this.heartbeatInterval = options.heartbeatInterval || 30000;
|
||
this.heartbeatTimer = null;
|
||
|
||
// 事件监听器
|
||
this.listeners = {
|
||
onOpen: [],
|
||
onMessage: [],
|
||
onClose: [],
|
||
onError: [],
|
||
onStateChange: []
|
||
};
|
||
}
|
||
|
||
// 连接WebSocket
|
||
connect() {
|
||
if (this.connectionState === 'CONNECTING' || this.connectionState === 'CONNECTED') {
|
||
return;
|
||
}
|
||
|
||
this.setState('CONNECTING');
|
||
this.ws = new WebSocket(this.url);
|
||
|
||
this.ws.onopen = (event) => {
|
||
this.setState('CONNECTED');
|
||
this.reconnectAttempts = 0;
|
||
this.startHeartbeat();
|
||
this.emit('onOpen', event);
|
||
};
|
||
|
||
this.ws.onmessage = (event) => {
|
||
const message = JSON.parse(event.data);
|
||
this.emit('onMessage', message);
|
||
};
|
||
|
||
this.ws.onclose = (event) => {
|
||
this.setState('DISCONNECTED');
|
||
this.stopHeartbeat();
|
||
this.emit('onClose', event);
|
||
|
||
// 自动重连
|
||
if (!event.wasClean && this.reconnectAttempts < this.maxReconnectAttempts) {
|
||
setTimeout(() => {
|
||
this.reconnectAttempts++;
|
||
this.connect();
|
||
}, this.reconnectDelay * Math.pow(2, this.reconnectAttempts)); // 指数退避
|
||
}
|
||
};
|
||
|
||
this.ws.onerror = (event) => {
|
||
this.setState('ERROR');
|
||
this.emit('onError', event);
|
||
};
|
||
}
|
||
|
||
// 断开连接
|
||
disconnect() {
|
||
if (this.ws) {
|
||
this.ws.close(1000, 'Client disconnect');
|
||
this.ws = null;
|
||
}
|
||
this.stopHeartbeat();
|
||
this.setState('DISCONNECTED');
|
||
}
|
||
|
||
// 发送消息
|
||
send(message) {
|
||
if (this.connectionState === 'CONNECTED' && this.ws) {
|
||
this.ws.send(JSON.stringify(message));
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// 心跳检测
|
||
startHeartbeat() {
|
||
this.heartbeatTimer = setInterval(() => {
|
||
if (this.connectionState === 'CONNECTED') {
|
||
this.send({ type: 'ping' });
|
||
}
|
||
}, this.heartbeatInterval);
|
||
}
|
||
|
||
stopHeartbeat() {
|
||
if (this.heartbeatTimer) {
|
||
clearInterval(this.heartbeatTimer);
|
||
this.heartbeatTimer = null;
|
||
}
|
||
}
|
||
|
||
// 状态管理
|
||
setState(newState) {
|
||
if (this.connectionState !== newState) {
|
||
const oldState = this.connectionState;
|
||
this.connectionState = newState;
|
||
this.emit('onStateChange', { oldState, newState });
|
||
}
|
||
}
|
||
|
||
// 事件系统
|
||
on(event, callback) {
|
||
if (this.listeners[event]) {
|
||
this.listeners[event].push(callback);
|
||
}
|
||
}
|
||
|
||
off(event, callback) {
|
||
if (this.listeners[event]) {
|
||
const index = this.listeners[event].indexOf(callback);
|
||
if (index > -1) {
|
||
this.listeners[event].splice(index, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
emit(event, data) {
|
||
if (this.listeners[event]) {
|
||
this.listeners[event].forEach(callback => callback(data));
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 使用示例
|
||
|
||
```javascript
|
||
// 创建WebSocket管理器
|
||
const wsManager = new WebSocketManager(
|
||
'ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin',
|
||
{
|
||
maxReconnectAttempts: 5,
|
||
reconnectDelay: 1000,
|
||
heartbeatInterval: 30000
|
||
}
|
||
);
|
||
|
||
// 监听连接状态变化
|
||
wsManager.on('onStateChange', ({ oldState, newState }) => {
|
||
console.log(`连接状态变化: ${oldState} -> ${newState}`);
|
||
updateUI(newState);
|
||
});
|
||
|
||
// 监听消息
|
||
wsManager.on('onMessage', (message) => {
|
||
handleMessage(message);
|
||
});
|
||
|
||
// 监听错误
|
||
wsManager.on('onError', (error) => {
|
||
console.error('WebSocket错误:', error);
|
||
showErrorNotification('连接出现错误,正在尝试重连...');
|
||
});
|
||
|
||
// 连接
|
||
wsManager.connect();
|
||
|
||
// 发送消息(带重试)
|
||
function sendMessageWithRetry(message, maxRetries = 3) {
|
||
let retries = 0;
|
||
|
||
function attemptSend() {
|
||
if (wsManager.send(message)) {
|
||
return true;
|
||
}
|
||
|
||
if (retries < maxRetries && wsManager.connectionState !== 'CONNECTED') {
|
||
retries++;
|
||
setTimeout(attemptSend, 1000);
|
||
} else {
|
||
console.error('发送消息失败:', message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return attemptSend();
|
||
}
|
||
```
|
||
|
||
## 错误处理完整指南
|
||
|
||
### 错误分类和处理策略
|
||
|
||
#### 1. 连接错误
|
||
|
||
**网络连接失败**
|
||
```javascript
|
||
// 错误场景:网络不可达、服务器关闭
|
||
wsManager.on('onError', (event) => {
|
||
if (event.code === 1006) { // 异常关闭
|
||
showNotification('网络连接中断,正在尝试重连...', 'warning');
|
||
// 自动重连逻辑已在管理器中处理
|
||
}
|
||
});
|
||
```
|
||
|
||
**认证失败**
|
||
```javascript
|
||
// 错误场景:client_id或user_id无效
|
||
wsManager.on('onMessage', (message) => {
|
||
if (message.type === 'error' && message.message.includes('认证')) {
|
||
showNotification('认证失败,请重新登录', 'error');
|
||
redirectToLogin();
|
||
}
|
||
});
|
||
```
|
||
|
||
#### 2. 业务错误
|
||
|
||
**软件操作错误**
|
||
```javascript
|
||
// 错误响应示例
|
||
{
|
||
"type": "error",
|
||
"message": "启动软件失败: 软件路径不存在",
|
||
"error_code": "SOFTWARE_NOT_FOUND",
|
||
"timestamp": "2024-01-01T10:00:00Z"
|
||
}
|
||
|
||
// 处理方式
|
||
function handleSoftwareError(message) {
|
||
const errorHandlers = {
|
||
'SOFTWARE_NOT_FOUND': () => {
|
||
showNotification('软件未找到,请检查软件配置', 'error');
|
||
// 可以引导用户到配置页面
|
||
},
|
||
'SOFTWARE_ALREADY_RUNNING': () => {
|
||
showNotification('软件已在运行中', 'info');
|
||
// 更新软件状态显示
|
||
},
|
||
'INSUFFICIENT_PERMISSIONS': () => {
|
||
showNotification('权限不足,无法执行操作', 'error');
|
||
// 可能需要提升权限
|
||
}
|
||
};
|
||
|
||
const handler = errorHandlers[message.error_code];
|
||
if (handler) {
|
||
handler();
|
||
} else {
|
||
showNotification(message.message, 'error');
|
||
}
|
||
}
|
||
```
|
||
|
||
**参数验证错误**
|
||
```javascript
|
||
// 前端参数验证
|
||
function validateLogOperation(params) {
|
||
const errors = [];
|
||
|
||
if (!params.operation || params.operation.length === 0) {
|
||
errors.push('operation字段不能为空');
|
||
}
|
||
if (params.operation && params.operation.length > 100) {
|
||
errors.push('operation字段长度不能超过100字符');
|
||
}
|
||
if (params.details && params.details.length > 1000) {
|
||
errors.push('details字段长度不能超过1000字符');
|
||
}
|
||
if (params.duration && (params.duration < 0 || params.duration > 3600)) {
|
||
errors.push('duration字段值必须在0-3600范围内');
|
||
}
|
||
|
||
return errors;
|
||
}
|
||
|
||
// 使用示例
|
||
function logUserOperation(params) {
|
||
const errors = validateLogOperation(params);
|
||
if (errors.length > 0) {
|
||
showNotification(`参数错误: ${errors.join(', ')}`, 'error');
|
||
return;
|
||
}
|
||
|
||
wsManager.send({
|
||
type: 'log_operation',
|
||
...params
|
||
});
|
||
}
|
||
```
|
||
|
||
#### 3. 常见错误代码表
|
||
|
||
| 错误代码 | 描述 | 处理建议 |
|
||
|---------|------|---------|
|
||
| `INVALID_MESSAGE_FORMAT` | 消息格式错误 | 检查JSON格式,重新发送 |
|
||
| `UNKNOWN_MESSAGE_TYPE` | 未知消息类型 | 检查type字段值 |
|
||
| `MISSING_REQUIRED_PARAMETER` | 缺少必填参数 | 补充必填参数 |
|
||
| `SOFTWARE_NOT_FOUND` | 软件未找到 | 检查software_id,更新软件配置 |
|
||
| `SOFTWARE_ALREADY_RUNNING` | 软件已运行 | 更新UI状态,无需重复启动 |
|
||
| `PERMISSION_DENIED` | 权限不足 | 联系管理员或重新认证 |
|
||
| `OPERATION_TIMEOUT` | 操作超时 | 检查网络连接,重试操作 |
|
||
| `SERVER_INTERNAL_ERROR` | 服务器内部错误 | 稍后重试,联系技术支持 |
|
||
|
||
## 开发注意事项
|
||
|
||
1. **纯WebSocket架构**: 所有功能通过WebSocket实现,提供实时双向通信
|
||
2. **CORS已配置**: 允许所有来源,生产环境需要修改
|
||
3. **连接管理**: 实现完整的连接状态管理和自动重连机制
|
||
4. **参数验证**: 前端应进行客户端验证,提升用户体验
|
||
5. **错误处理**: 提供统一的错误响应格式和处理策略
|
||
6. **心跳检测**: 定期发送ping消息保持连接活跃
|
||
7. **消息格式**: 所有WebSocket消息采用统一JSON格式
|
||
8. **重连策略**: 使用指数退避算法避免服务器压力
|
||
|
||
## 联系与支持
|
||
|
||
如有问题请参考项目代码或联系开发团队。
|
||
|
||
---
|
||
*文档版本: 1.0.0*
|
||
*最后更新: 2024-01-01* |