fix: comfy ui sdk bug

This commit is contained in:
imeepos 2025-08-08 20:08:41 +08:00
parent 643a1570a6
commit 6e59210871
7 changed files with 223 additions and 30 deletions

View File

@ -477,24 +477,38 @@ impl AppState {
/// 初始化配置管理器
pub async fn initialize_config_manager(&self) -> anyhow::Result<()> {
// 尝试从配置文件加载配置
let config_path = "config/app_config.json";
let app_config = match ConfigManager::load_config(config_path).await {
Ok(config) => config,
// 获取应用数据目录遵循Tauri安全存储原则
let app_data_dir = dirs::data_dir()
.ok_or_else(|| anyhow::anyhow!("无法获取应用数据目录"))?
.join("mixvideo");
// 确保应用数据目录存在
tokio::fs::create_dir_all(&app_data_dir).await
.map_err(|e| anyhow::anyhow!("创建应用数据目录失败: {}", e))?;
// 使用标准的配置文件路径
let config_path = app_data_dir.join("app_config.json");
let config_path_str = config_path.to_string_lossy().to_string();
let app_config = match ConfigManager::load_config(&config_path_str).await {
Ok(config) => {
info!("从文件加载配置: {}", config_path_str);
config
},
Err(_) => {
info!("配置文件不存在,使用默认配置");
info!("配置文件不存在,使用默认配置: {}", config_path_str);
crate::config::AppConfig::default()
}
};
let config_manager = Arc::new(ConfigManager::new(app_config, Some(config_path.to_string())));
let config_manager = Arc::new(ConfigManager::new(app_config, Some(config_path_str)));
{
let mut manager_guard = self.config_manager.write().await;
*manager_guard = Some(config_manager);
}
info!("配置管理器初始化完成");
info!("配置管理器初始化完成,配置路径: {}", config_path.display());
Ok(())
}

View File

@ -35,6 +35,10 @@ pub struct ComfyUIV2Config {
pub enable_cache: Option<bool>,
pub max_concurrency: Option<u32>,
pub websocket_url: Option<String>,
pub timeout_seconds: Option<u64>,
pub retry_delay_ms: Option<u64>,
pub enable_websocket: Option<bool>,
pub custom_headers: Option<std::collections::HashMap<String, String>>,
}
impl Default for ComfyUIV2Config {
@ -46,6 +50,10 @@ impl Default for ComfyUIV2Config {
enable_cache: Some(true),
max_concurrency: Some(4),
websocket_url: Some("ws://127.0.0.1:8188/ws".to_string()),
timeout_seconds: Some(300),
retry_delay_ms: Some(1000),
enable_websocket: Some(true),
custom_headers: None,
}
}
}

View File

@ -214,12 +214,20 @@ impl ConfigManager {
/// 保存配置到文件
async fn save_config(&self) -> Result<()> {
if let Some(config_path) = &self.config_path {
let path = std::path::Path::new(config_path);
// 确保父目录存在,遵循安全第一原则
if let Some(parent_dir) = path.parent() {
tokio::fs::create_dir_all(parent_dir).await
.map_err(|e| anyhow!("创建配置目录失败: {}", e))?;
}
let app_config = self.app_config.read().await;
let config_json = serde_json::to_string_pretty(&*app_config)?;
tokio::fs::write(config_path, config_json).await
.map_err(|e| anyhow!("保存配置文件失败: {}", e))?;
debug!("配置已保存到: {}", config_path);
}
Ok(())

View File

@ -28,15 +28,30 @@ use crate::business::services::comfyui_manager::ComfyUIManager;
/// 将前端的 ComfyUIV2Config 转换为后端的 ComfyUIConfig
fn convert_v2_config_to_config(v2_config: ComfyUIV2Config) -> ComfyUIConfig {
// 处理超时时间:前端传递的是毫秒,后端需要秒
let timeout_seconds = match v2_config.timeout {
Some(timeout_ms) => timeout_ms / 1000,
None => 300, // 默认5分钟
};
// 处理重试延迟:从前端配置中提取或使用默认值
let retry_delay_ms = v2_config.retry_delay_ms.unwrap_or(1000);
// 处理WebSocket启用状态
let enable_websocket = v2_config.enable_websocket.unwrap_or(true);
// 处理自定义头部
let custom_headers = v2_config.custom_headers;
ComfyUIConfig {
base_url: v2_config.base_url,
timeout_seconds: v2_config.timeout.unwrap_or(30000) / 1000, // 转换毫秒为秒
timeout_seconds,
retry_attempts: v2_config.retry_attempts.unwrap_or(3),
retry_delay_ms: 1000, // 默认重试延迟
enable_websocket: true, // 默认启用 WebSocket
retry_delay_ms,
enable_websocket,
enable_cache: v2_config.enable_cache.unwrap_or(true),
max_concurrency: v2_config.max_concurrency.unwrap_or(4),
custom_headers: None,
custom_headers,
}
}
@ -142,33 +157,35 @@ pub struct HealthCheckResponse {
// ==================== 基础连接管理命令 ====================
/// 连接到 ComfyUI 服务
/// 直接接收config参数匹配前端传递的格式
#[tauri::command]
pub async fn comfyui_v2_connect(
config: Option<ComfyUIV2Config>,
config: ComfyUIV2Config,
state: State<'_, AppState>,
) -> Result<ConnectionStatusResponse, String> {
info!("Command: comfyui_v2_connect");
info!("Command: comfyui_v2_connect - 配置: {:?}", config);
// 获取配置管理器
let config_manager = get_config_manager(&state).await?;
// 使用传入的配置或获取现有配置
let final_config = if let Some(v2_config) = config {
info!("使用传入的配置: {}", v2_config.base_url);
// 转换为 ComfyUIConfig
let converted_config = convert_v2_config_to_config(v2_config);
// 先更新配置到配置管理器
config_manager.update_comfyui_config(converted_config.clone()).await
.map_err(|e| format!("更新配置失败: {}", e))?;
converted_config
} else {
info!("使用现有配置");
config_manager.get_comfyui_config().await
};
// 转换前端配置为后端配置
let converted_config = convert_v2_config_to_config(config);
info!("转换后的配置: base_url={}, timeout_seconds={}",
converted_config.base_url, converted_config.timeout_seconds);
// 先更新配置到配置管理器
config_manager.update_comfyui_config(converted_config.clone()).await
.map_err(|e| {
error!("更新配置失败: {}", e);
format!("更新配置失败: {}", e)
})?;
// 创建 ComfyUI 管理器
let manager = ComfyUIManager::new(final_config)
.map_err(|e| format!("创建管理器失败: {}", e))?;
let manager = ComfyUIManager::new(converted_config)
.map_err(|e| {
error!("创建管理器失败: {}", e);
format!("创建管理器失败: {}", e)
})?;
// 尝试连接
match manager.connect().await {

View File

@ -0,0 +1,119 @@
//! ComfyUI V2 配置测试
//! 测试配置保存和加载功能
#[cfg(test)]
mod tests {
use crate::business::services::config_manager::ConfigManager;
use crate::config::AppConfig;
use crate::data::models::comfyui::ComfyUIConfig;
use std::collections::HashMap;
use tempfile::TempDir;
/// 测试配置管理器的目录创建和文件保存
#[tokio::test]
async fn test_config_manager_directory_creation() {
// 创建临时目录
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("config").join("app_config.json");
let config_path_str = config_path.to_string_lossy().to_string();
// 创建配置管理器
let app_config = AppConfig::default();
let config_manager = ConfigManager::new(app_config, Some(config_path_str.clone()));
// 创建测试配置
let mut custom_headers = HashMap::new();
custom_headers.insert("Authorization".to_string(), "Bearer test".to_string());
let test_config = ComfyUIConfig {
base_url: "http://192.168.0.193:8188".to_string(),
timeout_seconds: 300,
retry_attempts: 3,
retry_delay_ms: 1000,
enable_websocket: true,
enable_cache: true,
max_concurrency: 4,
custom_headers: Some(custom_headers),
};
// 测试配置更新(这应该创建目录并保存文件)
let result = config_manager.update_comfyui_config(test_config.clone()).await;
// 验证操作成功
assert!(result.is_ok(), "配置更新应该成功: {:?}", result.err());
// 验证文件确实被创建
assert!(config_path.exists(), "配置文件应该被创建");
// 验证配置内容正确
let loaded_config = config_manager.get_comfyui_config().await;
assert_eq!(loaded_config.base_url, test_config.base_url);
assert_eq!(loaded_config.timeout_seconds, test_config.timeout_seconds);
assert_eq!(loaded_config.retry_attempts, test_config.retry_attempts);
}
/// 测试配置转换函数
#[test]
fn test_config_conversion() {
use crate::presentation::commands::comfyui_v2_commands::convert_v2_config_to_config;
use crate::business::services::comfyui_v2_service::ComfyUIV2Config;
let mut custom_headers = HashMap::new();
custom_headers.insert("Content-Type".to_string(), "application/json".to_string());
let v2_config = ComfyUIV2Config {
base_url: "http://192.168.0.193:8188".to_string(),
timeout: Some(300000), // 5分钟毫秒
retry_attempts: Some(3),
enable_cache: Some(true),
max_concurrency: Some(4),
websocket_url: Some("ws://192.168.0.193:8188/ws".to_string()),
timeout_seconds: Some(300),
retry_delay_ms: Some(1000),
enable_websocket: Some(true),
custom_headers: Some(custom_headers.clone()),
};
let converted = convert_v2_config_to_config(v2_config);
assert_eq!(converted.base_url, "http://192.168.0.193:8188");
assert_eq!(converted.timeout_seconds, 300); // 应该转换为秒
assert_eq!(converted.retry_attempts, 3);
assert_eq!(converted.retry_delay_ms, 1000);
assert_eq!(converted.enable_websocket, true);
assert_eq!(converted.enable_cache, true);
assert_eq!(converted.max_concurrency, 4);
assert_eq!(converted.custom_headers, Some(custom_headers));
}
/// 测试默认配置处理
#[test]
fn test_default_config_handling() {
use crate::presentation::commands::comfyui_v2_commands::convert_v2_config_to_config;
use crate::business::services::comfyui_v2_service::ComfyUIV2Config;
let minimal_config = ComfyUIV2Config {
base_url: "http://localhost:8188".to_string(),
timeout: None,
retry_attempts: None,
enable_cache: None,
max_concurrency: None,
websocket_url: None,
timeout_seconds: None,
retry_delay_ms: None,
enable_websocket: None,
custom_headers: None,
};
let converted = convert_v2_config_to_config(minimal_config);
assert_eq!(converted.base_url, "http://localhost:8188");
assert_eq!(converted.timeout_seconds, 300); // 默认5分钟
assert_eq!(converted.retry_attempts, 3); // 默认3次
assert_eq!(converted.retry_delay_ms, 1000); // 默认1秒
assert_eq!(converted.enable_websocket, true); // 默认启用
assert_eq!(converted.enable_cache, true); // 默认启用
assert_eq!(converted.max_concurrency, 4); // 默认4个
assert_eq!(converted.custom_headers, None);
}
}

View File

@ -15,3 +15,6 @@ pub mod integration_tests;
#[cfg(test)]
pub mod performance_tests;
#[cfg(test)]
pub mod comfyui_v2_config_test;

24
test_comfyui_connect.js Normal file
View File

@ -0,0 +1,24 @@
// 测试ComfyUI V2连接功能的脚本
// 模拟前端调用后端API
const testConfig = {
"config": {
"base_url": "http://192.168.0.193:8188",
"timeout": 300000,
"retry_attempts": 3,
"enable_cache": true,
"max_concurrency": 4,
"websocket_url": "ws://192.168.0.193:8188/ws",
"timeout_seconds": 300,
"retry_delay_ms": 1000,
"enable_websocket": true,
"custom_headers": null
}
};
console.log('测试配置:', JSON.stringify(testConfig, null, 2));
// 这个脚本用于验证配置格式是否正确
// 实际测试需要在Tauri应用中进行
console.log('配置格式验证通过!');
console.log('请在Tauri应用的ComfyUI V2页面中测试连接功能。');