You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

130 lines
3.3 KiB

// 工具类代理管理器
import LCCScript from '@/core/script/LCCScript.ts'
export default class ToolProxyManager {
// 存储所有活跃的 MessageChannel 端口
private activePorts = new WeakMap<Worker, MessagePort>()
/**
* 为 Worker 创建工具代理
*/
createToolProxyForWorker(worker: Worker): MessagePort {
// 创建 MessageChannel 用于通信
const channel = new MessageChannel()
// 存储 port2 用于后续通信
this.activePorts.set(worker, channel.port2)
// 设置 port2 的消息监听器
channel.port2.onmessage = (event) => {
this.handleWorkerCall(worker, event)
}
channel.port2.start()
// 返回 port1 供 Worker 使用
return channel.port1
}
/**
* 处理来自 Worker 的调用请求
*/
handleWorkerCall(worker: Worker, event: MessageEvent): void {
const { data } = event
if (data?.type !== 'call') return
const { tool, method, callId, args } = data
const port = this.activePorts.get(worker)
if (!port) {
console.error(`[ToolProxy] 找不到 worker 的端口`, worker)
return
}
// 获取主线程中的工具实例
const toolInstance = (window as any)[tool]
if (!toolInstance) {
console.error(`[ToolProxy] 工具未找到: ${tool}`)
port.postMessage({
type: 'error',
tool,
method,
callId,
error: {
name: 'ToolNotFound',
message: `${tool} is not available`
}
})
return
}
if (typeof toolInstance[method] !== 'function') {
console.error(`[ToolProxy] 方法未找到: ${tool}.${method}`)
port.postMessage({
type: 'error', tool, method, callId,
error: {
name: 'MethodNotFound',
message: `${tool}.${method} is not a function`
}
})
return
}
try {
// 执行工具方法
let result
if (toolInstance instanceof LCCScript && method === 'log') {
// 特殊处理 LCCScript 的 log 方法
result = toolInstance[method]('Script-' + worker['name'], ...args)
} else {
result = toolInstance[method](...args)
}
// 处理异步函数
if (result instanceof Promise) {
result.then(
resolved => {
port.postMessage({
type: 'result', tool, method, callId, result: resolved
})
},
error => {
port.postMessage({
type: 'error', tool, method, callId,
error: {
name: error.name || 'PromiseRejection',
message: error.message,
stack: error.stack
}
})
}
)
}
// 处理同步函数
else {
port.postMessage({ type: 'result', tool, method, callId, result })
}
} catch (error) {
console.error(`[ToolProxy] 执行错误: ${tool}.${method}`, error)
port.postMessage({
type: 'error', tool, method, callId,
error: {
name: error.name || 'ExecutionError',
message: error.message,
stack: error.stack
}
})
}
}
/**
* 清理 Worker 资源
*/
cleanupWorker(worker: Worker) {
const port = this.activePorts.get(worker)
if (port) {
port.close()
this.activePorts.delete(worker)
}
}
}