shuzhiren-comfyui/任务队列后端/utils/mdWebSocketServer.js

133 lines
3.6 KiB
JavaScript

import { WebSocketServer as WSServer } from 'ws';
import dotenv from 'dotenv';
dotenv.config();
class MDWebSocketServer {
constructor() {
this.wss = null;
this.connectedClients = new Map();
this.currentJwtToken = null;
this.currentCapacity = { internal: 0, external: 0 };
this.instances = new Map();
this.port = process.env.MESSAGE_DISPATCHER_WS_PORT || 8087;
}
async init() {
return new Promise((resolve, reject) => {
this.wss = new WSServer({ port: this.port });
this.wss.on('listening', () => {
console.log(`[MDWebSocketServer] WebSocket 服务已启动,端口: ${this.port}`);
resolve();
});
this.wss.on('connection', (ws) => {
console.log('[MDWebSocketServer] 新的 WebSocket 连接已建立');
const clientId = Date.now().toString();
this.connectedClients.set(clientId, ws);
ws.on('message', (data) => {
this.handleMessage(ws, data);
});
ws.on('close', () => {
console.log('[MDWebSocketServer] WebSocket 连接已关闭');
this.connectedClients.delete(clientId);
});
ws.on('error', (error) => {
console.error('[MDWebSocketServer] WebSocket 连接错误:', error);
this.connectedClients.delete(clientId);
});
});
this.wss.on('error', (error) => {
console.error('[MDWebSocketServer] WebSocket 服务错误:', error);
reject(error);
});
});
}
handleMessage(ws, data) {
try {
const message = JSON.parse(data.toString());
console.log(`[MDWebSocketServer] 收到消息: ${message.type}`);
switch (message.type) {
case 'JWT_UPDATE':
this.handleJwtUpdate(message.data);
break;
case 'CAPACITY_UPDATE':
this.handleCapacityUpdate(message.data);
break;
case 'INSTANCE_ONLINE':
this.handleInstanceOnline(message.data);
break;
case 'INSTANCE_OFFLINE':
this.handleInstanceOffline(message.data);
break;
case 'HEARTBEAT':
this.handleHeartbeat(message.data, ws);
break;
default:
console.log('[MDWebSocketServer] 未知消息类型:', message.type);
}
} catch (error) {
console.error('[MDWebSocketServer] 解析消息失败:', error);
}
}
handleJwtUpdate(data) {
this.currentJwtToken = data.token;
console.log('[MDWebSocketServer] JWT Token 已更新');
}
handleCapacityUpdate(data) {
if (data.summary) {
this.currentCapacity.internal = data.summary.onlineInstances - data.summary.busyInstances;
console.log(`[MDWebSocketServer] 算力状态已更新: 内部可用 = ${this.currentCapacity.internal}`);
}
}
handleInstanceOnline(data) {
this.instances.set(data.instanceId, { ...data, status: 'online' });
console.log(`[MDWebSocketServer] 实例上线: ${data.instanceId}`);
}
handleInstanceOffline(data) {
this.instances.set(data.instanceId, { ...data, status: 'offline' });
console.log(`[MDWebSocketServer] 实例下线: ${data.instanceId}`);
}
handleHeartbeat(data, ws) {
ws.send(JSON.stringify({
type: 'HEARTBEAT_ACK',
data: { timestamp: new Date().toISOString() }
}));
}
getJwtToken() {
return this.currentJwtToken;
}
getInternalCapacity() {
return this.currentCapacity.internal;
}
getExternalCapacity() {
return parseInt(process.env.EXTERNAL_CAPACITY_MAX) || 10;
}
getInstances() {
return Array.from(this.instances.values());
}
hasConnectedClients() {
return this.connectedClients.size > 0;
}
}
export default new MDWebSocketServer();