refactor: 移除心跳机制相关代码,简化服务器管理逻辑,更新文档以反映最新功能和配置

This commit is contained in:
iHeyTang
2025-08-19 14:48:39 +08:00
parent 84e4575717
commit c0354b35d2
6 changed files with 91 additions and 745 deletions

View File

@@ -1,413 +1,44 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
// 检测ComfyUI服务端口的函数
async function detectComfyUIPort(host) {
try {
const currentPort = window.location.port;
if (currentPort) {
console.log(`从当前页面URL获取端口: ${currentPort}`);
return parseInt(currentPort);
}
} catch (error) {
console.warn("无法从当前页面获取端口:", error);
}
// 默认返回8188
console.warn("无法检测到ComfyUI端口使用默认端口8188");
return 8188;
}
// 获取本地IP地址的函数
async function getLocalIPAddress() {
try {
// 尝试通过WebRTC获取本地IP地址
const pc = new RTCPeerConnection({
iceServers: [],
});
pc.createDataChannel("");
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
return new Promise((resolve) => {
pc.onicecandidate = (event) => {
if (event.candidate) {
const ipMatch = event.candidate.candidate.match(
/([0-9]{1,3}(\.[0-9]{1,3}){3})/
);
if (ipMatch) {
const localIP = ipMatch[1];
// 保留有效的内网IP地址
if (
localIP.startsWith("192.168.") ||
localIP.startsWith("10.") ||
localIP.startsWith("172.") ||
localIP === "127.0.0.1"
) {
pc.close();
resolve(localIP);
}
}
}
};
// 超时处理
setTimeout(() => {
pc.close();
resolve("127.0.0.1"); // 如果获取失败,使用默认地址
}, 3000);
});
} catch (error) {
console.warn("无法获取本地IP地址使用默认地址:", error);
return "127.0.0.1";
}
}
// 本地存储的 key
const COMFY_SERVER_REGISTRATION_KEY = "comfyui_server_registration";
const WORKFLOW_SERVICE_HOST_KEY = "workflow_publisher_service_host";
// ComfyUI服务器注册配置 - 使用动态IP地址
let DEFAULT_SERVER_CONFIG = {
name: "comfyui_node_1",
http_url: "http://127.0.0.1:8188", // 将在初始化时更新为实际IP
workflow_service_host: "http://localhost:8000",
};
// 默认工作流服务地址
const DEFAULT_WORKFLOW_SERVICE_HOST = "http://localhost:8000";
// 初始化默认配置
async function initializeDefaultConfig() {
// 获取工作流服务地址
function getWorkflowServiceHost() {
try {
const localIP = await getLocalIPAddress();
const port = await detectComfyUIPort(localIP);
DEFAULT_SERVER_CONFIG.http_url = `http://${localIP}:${port}`;
console.log("自动获取本地IP地址和端口:", localIP, port);
const stored = localStorage.getItem(WORKFLOW_SERVICE_HOST_KEY);
return stored || DEFAULT_WORKFLOW_SERVICE_HOST;
} catch (error) {
console.warn("初始化IP地址和端口失败使用默认地址:", error);
console.error("读取工作流服务地址失败:", error);
return DEFAULT_WORKFLOW_SERVICE_HOST;
}
}
// 获取ComfyUI服务器注册配置
function getComfyServerConfig() {
// 保存工作流服务地址
function saveWorkflowServiceHost(host) {
try {
const stored = localStorage.getItem(COMFY_SERVER_REGISTRATION_KEY);
return stored ? JSON.parse(stored) : { ...DEFAULT_SERVER_CONFIG };
localStorage.setItem(WORKFLOW_SERVICE_HOST_KEY, host);
} catch (error) {
console.error("读取ComfyUI服务器配置失败:", error);
return { ...DEFAULT_SERVER_CONFIG };
console.error("保存工作流服务地址失败:", error);
}
}
// 保存ComfyUI服务器注册配置
function saveComfyServerConfig(config) {
try {
localStorage.setItem(COMFY_SERVER_REGISTRATION_KEY, JSON.stringify(config));
} catch (error) {
console.error("保存ComfyUI服务器配置失败:", error);
}
}
// 获取本地设置
function getLocalSettings() {
try {
const stored = localStorage.getItem("workflow_publisher_settings");
return stored ? JSON.parse(stored) : { host: "" };
} catch (error) {
console.error("读取本地设置失败:", error);
return { host: "" };
}
}
// 保存本地设置
function saveLocalSettings(settings) {
try {
localStorage.setItem(
"workflow_publisher_settings",
JSON.stringify(settings)
);
} catch (error) {
console.error("保存本地设置失败:", error);
}
}
// ComfyUI服务器注册管理器
class ComfyServerManager {
constructor() {
this.registrationInterval = null;
this.heartbeatInterval = null;
this.isRegistered = false;
this.serverConfig = getComfyServerConfig();
}
// 注册服务器到工作流服务
async registerServer() {
if (!this.serverConfig.workflow_service_host) {
return { success: false, error: "未设置工作流服务地址" };
}
try {
const response = await fetch(
`${this.serverConfig.workflow_service_host}/api/comfy/register`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: this.serverConfig.name,
http_url: this.serverConfig.http_url,
ws_url: this.getWebSocketUrl(),
}),
}
);
if (response.ok) {
const result = await response.json();
console.log("ComfyUI服务器注册成功:", result);
this.isRegistered = true;
this.startHeartbeat();
return { success: true };
} else {
const errorText = await response.text();
const errorMessage = `HTTP ${response.status}: ${
errorText || "服务器响应错误"
}`;
console.error("ComfyUI服务器注册失败:", errorMessage);
return { success: false, error: errorMessage };
}
} catch (error) {
const errorMessage = `网络错误: ${error.message}`;
console.error("注册ComfyUI服务器时发生错误:", errorMessage);
return { success: false, error: errorMessage };
}
}
// 注销服务器
async unregisterServer() {
if (!this.serverConfig.workflow_service_host || !this.isRegistered) {
return { success: false, error: "未设置工作流服务地址或服务器未注册" };
}
try {
const response = await fetch(
`${this.serverConfig.workflow_service_host}/api/comfy/unregister`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: this.serverConfig.name }),
}
);
if (response.ok) {
console.log("ComfyUI服务器注销成功");
this.isRegistered = false;
this.stopHeartbeat();
return { success: true };
} else {
const errorText = await response.text();
const errorMessage = `HTTP ${response.status}: ${
errorText || "服务器响应错误"
}`;
console.error("ComfyUI服务器注销失败:", errorMessage);
return { success: false, error: errorMessage };
}
} catch (error) {
const errorMessage = `网络错误: ${error.message}`;
console.error("注销ComfyUI服务器时发生错误:", errorMessage);
return { success: false, error: errorMessage };
}
}
// 发送心跳
async sendHeartbeat() {
if (!this.serverConfig.workflow_service_host || !this.isRegistered) {
return false;
}
try {
const response = await fetch(
`${this.serverConfig.workflow_service_host}/api/comfy/heartbeat`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: this.serverConfig.name }),
}
);
if (response.ok) {
console.debug("心跳发送成功");
return true;
} else {
console.warn("心跳发送失败:", response.status);
// 如果心跳失败,尝试重新注册
if (response.status === 404) {
console.log("服务器不存在,尝试重新注册...");
this.isRegistered = false;
await this.registerServer();
}
return false;
}
} catch (error) {
console.error("发送心跳时发生错误:", error);
// 如果网络错误,尝试重新注册
this.isRegistered = false;
await this.registerServer();
return false;
}
}
// 启动心跳
startHeartbeat() {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval);
}
// 每30秒发送一次心跳
this.heartbeatInterval = setInterval(() => {
this.sendHeartbeat();
}, 30000);
console.log("ComfyUI服务器心跳已启动");
}
// 停止心跳
stopHeartbeat() {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval);
this.heartbeatInterval = null;
}
console.log("ComfyUI服务器心跳已停止");
}
// 更新服务器配置
updateConfig(newConfig) {
this.serverConfig = { ...this.serverConfig, ...newConfig };
saveComfyServerConfig(this.serverConfig);
// 如果已注册,需要重新注册以更新配置
if (this.isRegistered) {
this.unregisterServer().then((result) => {
if (result.success) {
setTimeout(() => this.registerServer(), 1000);
} else {
console.warn("更新配置时注销失败:", result.error);
}
});
}
}
// 设置工作流服务地址
setWorkflowServiceHost(host) {
this.serverConfig.workflow_service_host = host;
saveComfyServerConfig(this.serverConfig);
}
// 获取WebSocket URL自动从HTTP URL生成
getWebSocketUrl() {
if (!this.serverConfig.http_url) return "";
const url = new URL(this.serverConfig.http_url);
// 根据协议自动选择ws或wss
const protocol = url.protocol === "https:" ? "wss:" : "ws:";
return `${protocol}//${url.host}/ws`;
}
// 获取服务器状态
async getServerStatus() {
if (!this.serverConfig.workflow_service_host) {
return null;
}
try {
const response = await fetch(
`${this.serverConfig.workflow_service_host}/api/comfy/status/${this.serverConfig.name}`
);
if (response.ok) {
return await response.json();
}
} catch (error) {
console.error("获取服务器状态失败:", error);
}
return null;
}
// 获取系统健康状态
async getSystemHealth() {
if (!this.serverConfig.workflow_service_host) {
return null;
}
try {
const response = await fetch(
`${this.serverConfig.workflow_service_host}/api/comfy/health`
);
if (response.ok) {
return await response.json();
}
} catch (error) {
console.error("获取系统健康状态失败:", error);
}
return null;
}
// 动态更新IP地址和端口
async updateLocalIPAddress() {
try {
const localIP = await getLocalIPAddress();
const port = await detectComfyUIPort(localIP);
const newHttpUrl = `http://${localIP}:${port}`;
if (this.serverConfig.http_url !== newHttpUrl) {
this.serverConfig.http_url = newHttpUrl;
saveComfyServerConfig(this.serverConfig);
console.log("已更新本地IP地址和端口:", localIP, port);
return { ip: localIP, port: port };
}
return null;
} catch (error) {
console.warn("更新IP地址和端口失败:", error);
return null;
}
}
// 同步注册状态
syncRegistrationStatus() {
if (this.serverConfig.workflow_service_host) {
this.getServerStatus()
.then((status) => {
if (status) {
this.isRegistered = true;
console.log("同步注册状态: 已注册");
} else {
this.isRegistered = false;
console.log("同步注册状态: 未注册");
}
})
.catch((error) => {
console.warn("同步注册状态失败:", error);
this.isRegistered = false;
});
}
}
}
// 自定义 fetchApi 函数使用ComfyUI服务器配置中的工作流服务地址
// 自定义 fetchApi 函数,使用配置的工作流服务地址
async function customFetchApi(endpoint, options = {}) {
try {
// 从ComfyUI服务器配置获取工作流服务地址
const serverConfig = getComfyServerConfig();
// 如果没有配置工作流服务地址,回退到默认的 api.fetchApi
if (!serverConfig.workflow_service_host) {
const host = getWorkflowServiceHost();
if (!host) {
console.warn("未配置工作流服务地址,使用默认的 ComfyUI API");
return await api.fetchApi(endpoint, options);
}
// 构建完整的 URL
const host = serverConfig.workflow_service_host.replace(/\/$/, ""); // 移除末尾的斜杠
const fullUrl = `${host}${endpoint}`;
const fullHost = host.replace(/\/$/, ""); // 移除末尾的斜杠
const fullUrl = `${fullHost}${endpoint}`;
console.log(`使用工作流服务地址请求: ${fullUrl}`);
@@ -457,7 +88,7 @@ function createElement(tagName, props) {
return element;
}
// Modal class (保持不变)
// Modal class
class Modal {
constructor(id, title, full_width = false) {
this.id = id;
@@ -502,9 +133,6 @@ const createButton = (innerHTML, title, { onClick }) => {
app.registerExtension({
name: "Comfy.WorkflowPublisher",
async setup() {
// 初始化默认配置获取本地IP地址
await initializeDefaultConfig();
const addCustomStyles = () => {
const styleId = "jags-publisher-styles";
if (document.getElementById(styleId)) return;
@@ -552,21 +180,22 @@ app.registerExtension({
const iconGet = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" /></svg>`;
const iconPublish = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2" /><path d="M7 9l5-5 5 5" /><path d="M12 4v12" /></svg>`;
const iconSettings = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1 1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>`;
const btnGet = createButton(iconGet, "从服务器获取工作流", {
onClick: () => showWorkflowListDialog(),
});
const btnPublish = createButton(iconPublish, "发布当前工作流", {
onClick: () => showPublishDialog(),
});
const btnComfyServer = createButton(`🖥️`, "ComfyUI服务器管理", {
onClick: () => showComfyServerDialog(),
const btnSettings = createButton(iconSettings, "设置工作流服务地址", {
onClick: () => showSettingsDialog(),
});
const separator = document.createElement("div");
separator.style.cssText =
"border-left: 1px solid var(--border-color); height: 22px; margin: 0 4px;";
container.append(btnGet, btnPublish, btnComfyServer, separator);
container.append(btnGet, btnPublish, btnSettings, separator);
menu.insertBefore(container, menu.firstChild);
});
@@ -581,10 +210,9 @@ app.registerExtension({
true
);
const comfyServerDialog = new Modal(
"comfy-server-dialog",
"ComfyUI服务器管理",
true
const settingsDialog = new Modal(
"workflow-publisher-settings-dialog",
"设置工作流服务地址"
);
async function showWorkflowListDialog() {
@@ -708,297 +336,93 @@ app.registerExtension({
}
}
// ComfyUI 服务器管理对话框
async function showComfyServerDialog() {
// 设置对话框
async function showSettingsDialog() {
try {
const serverConfig = getComfyServerConfig();
const settings = getLocalSettings();
const currentHost = getWorkflowServiceHost();
// 创建服务器配置表单
const configForm = `
const settingsForm = `
<div style="display: flex; flex-direction: column; gap: 15px;">
<div>
<label for="server-name" style="display: block; margin-bottom: 5px;">当前服务节点名称:</label>
<input id="server-name" type="text" value="${
serverConfig.name
}" placeholder="例如: comfyui_node_1" style="width: 100%; box-sizing: border-box; background: var(--comfy-input-bg); color: var(--fg-color); border: 1px solid var(--border-color); padding: 8px; border-radius: 4px;">
<label for="workflow-service-host" style="display: block; margin-bottom: 5px;">工作流服务地址:</label>
<input id="workflow-service-host" type="text" value="${currentHost}" placeholder="例如: http://localhost:8000" style="width: 100%; box-sizing: border-box; background: var(--comfy-input-bg); color: var(--fg-color); border: 1px solid var(--border-color); padding: 8px; border-radius: 4px;">
<small style="color: var(--border-color); font-size: 0.9em;">这是用于获取和发布工作流的服务地址</small>
</div>
<div>
<label for="server-http-url" style="display: block; margin-bottom: 5px;">当前服务节点地址:</label>
<input id="server-http-url" type="text" value="${
serverConfig.http_url
}" placeholder="例如: http://127.0.0.1:8188" style="width: 100%; box-sizing: border-box; background: var(--comfy-input-bg); color: var(--fg-color); border: 1px solid var(--border-color); padding: 8px; border-radius: 4px;">
<small style="color: var(--border-color); font-size: 0.9em;">WebSocket地址将自动生成为: <span id="ws-url-preview">${
serverConfig.http_url
? serverConfig.http_url.replace(/^https?:\/\//, "ws://") +
"/ws"
: ""
}</span></small>
<div id="connection-status" style="padding: 10px; border-radius: 4px; background: var(--comfy-input-bg); border: 1px solid var(--border-color);">
<strong>连接状态:</strong> <span id="status-text">未测试</span>
</div>
<div>
<label for="workflow-service-host" style="display: block; margin-bottom: 5px;">工作流服务地址 (统一管理地址):</label>
<input id="workflow-service-host" type="text" value="${
settings.host
}" placeholder="例如: http://localhost:8000" style="width: 100%; box-sizing: border-box; background: var(--comfy-input-bg); color: var(--fg-color); border: 1px solid var(--border-color); padding: 8px; border-radius: 4px;">
</div>
<div id="server-status" style="padding: 10px; border-radius: 4px; background: var(--comfy-input-bg); border: 1px solid var(--border-color);">
<strong>服务器状态:</strong> <span id="status-text">未连接</span>
</div>
<div id="server-actions" style="display: flex; gap: 10px; flex-wrap: wrap;">
<button id="btn-register" class="jags-button" style="flex: 1; min-width: 120px;">注册服务器</button>
<button id="btn-unregister" class="jags-button" style="flex: 1; min-width: 120px;">注销服务器</button>
<button id="btn-refresh-status" class="jags-button" style="flex: 1; min-width: 120px;">刷新状态</button>
<button id="btn-refresh-ip" class="jags-button" style="flex: 1; min-width: 120px;">刷新IP和端口</button>
<div id="settings-actions" style="display: flex; gap: 10px; flex-wrap: wrap;">
<button id="btn-test-connection" class="jags-button" style="flex: 1; min-width: 120px;">测试连接</button>
<button id="btn-save-settings" class="jags-button" style="flex: 1; min-width: 120px;">保存设置</button>
</div>
</div>
`;
comfyServerDialog.setContent(configForm);
comfyServerDialog.addButtons([
{ label: "关闭", callback: () => comfyServerDialog.hide() },
settingsDialog.setContent(settingsForm);
settingsDialog.addButtons([
{ label: "关闭", callback: () => settingsDialog.hide() },
]);
comfyServerDialog.show();
// 初始化 ComfyServerManager
const serverManager = new ComfyServerManager();
if (settings.host) {
serverManager.setWorkflowServiceHost(settings.host);
// 同步注册状态
serverManager.syncRegistrationStatus();
}
settingsDialog.show();
// 绑定事件
const btnRegister = document.getElementById("btn-register");
const btnUnregister = document.getElementById("btn-unregister");
const btnRefreshStatus = document.getElementById("btn-refresh-status");
const btnRefreshIP = document.getElementById("btn-refresh-ip");
const btnTestConnection = document.getElementById(
"btn-test-connection"
);
const btnSaveSettings = document.getElementById("btn-save-settings");
const statusText = document.getElementById("status-text");
const hostInput = document.getElementById("workflow-service-host");
// 添加HTTP地址输入框的实时预览功能
const httpUrlInput = document.getElementById("server-http-url");
const wsUrlPreview = document.getElementById("ws-url-preview");
httpUrlInput.addEventListener("input", function () {
const httpUrl = this.value;
if (httpUrl) {
try {
const url = new URL(httpUrl);
// 根据协议自动选择ws或wss
const protocol = url.protocol === "https:" ? "wss:" : "ws:";
const wsUrl = `${protocol}//${url.host}/ws`;
wsUrlPreview.textContent = wsUrl;
} catch (error) {
wsUrlPreview.textContent = "无效的URL格式";
}
} else {
wsUrlPreview.textContent = "";
}
});
// 注册服务器
btnRegister.onclick = async () => {
const newConfig = {
name: document.getElementById("server-name").value,
http_url: document.getElementById("server-http-url").value,
};
const workflowHost = document.getElementById(
"workflow-service-host"
).value;
if (workflowHost) {
serverManager.setWorkflowServiceHost(workflowHost);
// 保存到本地设置
saveLocalSettings({ host: workflowHost });
}
serverManager.updateConfig(newConfig);
btnRegister.disabled = true;
btnRegister.textContent = "注册中...";
const result = await serverManager.registerServer();
if (result.success) {
statusText.textContent = "已注册";
statusText.style.color = "var(--success-color)";
btnRegister.textContent = "已注册";
btnRegister.disabled = true;
btnUnregister.disabled = false;
} else {
const errorMessage = result.error || "未知错误";
statusText.textContent = `注册失败: ${errorMessage}`;
statusText.style.color = "var(--error-color)";
btnRegister.textContent = "注册服务器";
btnRegister.disabled = false;
}
};
// 注销服务器
btnUnregister.onclick = async () => {
btnUnregister.disabled = true;
btnUnregister.textContent = "注销中...";
const result = await serverManager.unregisterServer();
if (result.success) {
statusText.textContent = "已注销";
statusText.style.color = "orange";
btnRegister.disabled = false;
btnRegister.textContent = "注册服务器";
btnUnregister.disabled = true;
btnUnregister.textContent = "注销服务器";
} else {
const errorMessage = result.error || "未知错误";
statusText.textContent = `注销失败: ${errorMessage}`;
statusText.style.color = "var(--error-color)";
btnUnregister.disabled = false;
btnUnregister.textContent = "注销服务器";
}
};
// 刷新状态
btnRefreshStatus.onclick = async () => {
if (settings.host) {
serverManager.setWorkflowServiceHost(settings.host);
const status = await serverManager.getServerStatus();
// 调试信息
console.log("服务器状态:", status);
if (status && status.last_heartbeat) {
console.log("最后心跳时间原始值:", status.last_heartbeat);
console.log("时间类型:", typeof status.last_heartbeat);
}
if (status) {
// 安全地处理时间显示
let heartbeatTime = "未知";
if (status.last_heartbeat) {
try {
// 尝试解析ISO格式的时间字符串
const date = new Date(status.last_heartbeat);
if (!isNaN(date.getTime())) {
heartbeatTime = date.toLocaleString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
});
} else {
heartbeatTime = "时间格式错误";
}
} catch (error) {
console.warn(
"时间解析失败:",
error,
"原始时间:",
status.last_heartbeat
);
heartbeatTime = "时间解析失败";
}
}
statusText.textContent = `在线 - 最后心跳: ${heartbeatTime}`;
statusText.style.color = "var(--success-color)";
// 同步更新本地注册状态
serverManager.isRegistered = true;
btnRegister.disabled = true;
btnRegister.textContent = "已注册";
btnUnregister.disabled = false;
} else {
statusText.textContent = "未注册";
statusText.style.color = "orange";
// 同步更新本地注册状态
serverManager.isRegistered = false;
btnRegister.disabled = false;
btnRegister.textContent = "注册服务器";
btnUnregister.disabled = true;
}
}
};
// 刷新IP地址和端口
btnRefreshIP.onclick = async () => {
btnRefreshIP.disabled = true;
btnRefreshIP.textContent = "刷新中...";
// 测试连接
btnTestConnection.onclick = async () => {
btnTestConnection.disabled = true;
btnTestConnection.textContent = "测试中...";
statusText.textContent = "正在测试连接...";
statusText.style.color = "orange";
try {
const result = await serverManager.updateLocalIPAddress();
if (result) {
// 更新输入框显示
document.getElementById(
"server-http-url"
).value = `http://${result.ip}:${result.port}`;
// 更新WebSocket预览
const wsUrlPreview = document.getElementById("ws-url-preview");
wsUrlPreview.textContent = `ws://${result.ip}:${result.port}/ws`;
const testHost = hostInput.value.trim();
if (!testHost) {
throw new Error("请输入工作流服务地址");
}
statusText.textContent = `IP地址和端口已更新为: ${result.ip}:${result.port}`;
const response = await fetch(`${testHost}/api/workflow`);
if (response.ok) {
statusText.textContent = "连接成功";
statusText.style.color = "var(--success-color)";
} else {
statusText.textContent = "IP地址和端口无需更新";
statusText.style.color = "orange";
}
} catch (error) {
statusText.textContent = `IP地址和端口更新失败: ${error.message}`;
statusText.style.color = "var(--error-color)";
} finally {
btnRefreshIP.disabled = false;
btnRefreshIP.textContent = "刷新IP和端口";
}
};
// 初始状态检查
if (settings.host) {
btnRefreshStatus.click();
} else {
// 如果没有设置工作流服务地址,确保按钮状态正确
btnRegister.disabled = false;
btnUnregister.disabled = true;
}
// 自动刷新IP地址和端口
setTimeout(async () => {
try {
const result = await serverManager.updateLocalIPAddress();
if (result) {
// 更新输入框显示
document.getElementById(
"server-http-url"
).value = `http://${result.ip}:${result.port}`;
// 更新WebSocket预览
const wsUrlPreview = document.getElementById("ws-url-preview");
wsUrlPreview.textContent = `ws://${result.ip}:${result.port}/ws`;
console.log(
"对话框显示时自动更新IP地址和端口:",
result.ip,
result.port
throw new Error(
`HTTP ${response.status}: ${response.statusText}`
);
}
} catch (error) {
console.warn("自动更新IP地址和端口失败:", error);
statusText.textContent = `连接失败: ${error.message}`;
statusText.style.color = "var(--error-color)";
} finally {
btnTestConnection.disabled = false;
btnTestConnection.textContent = "测试连接";
}
}, 500);
};
// 延迟同步按钮状态,确保与内部状态一致
setTimeout(() => {
if (serverManager.isRegistered) {
btnRegister.disabled = true;
btnRegister.textContent = "已注册";
btnUnregister.disabled = false;
} else {
btnRegister.disabled = false;
btnRegister.textContent = "注册服务器";
btnUnregister.disabled = true;
// 保存设置
btnSaveSettings.onclick = () => {
const newHost = hostInput.value.trim();
if (!newHost) {
alert("请输入工作流服务地址");
return;
}
}, 1000);
saveWorkflowServiceHost(newHost);
statusText.textContent = "设置已保存";
statusText.style.color = "var(--success-color)";
setTimeout(() => {
settingsDialog.hide();
}, 1000);
};
} catch (error) {
console.error("显示ComfyUI服务器管理对话框失败:", error);
console.error("显示设置对话框失败:", error);
alert(`显示对话框失败: ${error.message}`);
}
}