874 lines
23 KiB
TypeScript
874 lines
23 KiB
TypeScript
|
|
import { reactive, ref } from 'vue'
|
|||
|
|
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
|||
|
|
import type { IEventBuilder } from '@/events/IEventBuilder'
|
|||
|
|
|
|||
|
|
// 导入所有服务
|
|||
|
|
import { WindowService } from './WindowService'
|
|||
|
|
import { ResourceService } from './ResourceService'
|
|||
|
|
import { EventCommunicationService } from './EventCommunicationService'
|
|||
|
|
import { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
|
|||
|
|
import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
|
|||
|
|
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 系统服务配置接口
|
|||
|
|
*/
|
|||
|
|
export interface SystemServiceConfig {
|
|||
|
|
debug?: boolean
|
|||
|
|
maxMemoryUsage?: number
|
|||
|
|
maxCpuUsage?: number
|
|||
|
|
enablePerformanceMonitoring?: boolean
|
|||
|
|
enableSecurityAudit?: boolean
|
|||
|
|
autoCleanup?: boolean
|
|||
|
|
cleanupInterval?: number
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 系统状态接口
|
|||
|
|
*/
|
|||
|
|
export interface SystemStatus {
|
|||
|
|
initialized: boolean
|
|||
|
|
running: boolean
|
|||
|
|
servicesStatus: {
|
|||
|
|
windowService: boolean
|
|||
|
|
resourceService: boolean
|
|||
|
|
eventService: boolean
|
|||
|
|
sandboxEngine: boolean
|
|||
|
|
lifecycleManager: boolean
|
|||
|
|
}
|
|||
|
|
performance: {
|
|||
|
|
memoryUsage: number
|
|||
|
|
cpuUsage: number
|
|||
|
|
activeApps: number
|
|||
|
|
activeWindows: number
|
|||
|
|
}
|
|||
|
|
uptime: number
|
|||
|
|
lastError?: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* SDK调用接口
|
|||
|
|
*/
|
|||
|
|
export interface SDKCall {
|
|||
|
|
requestId: string
|
|||
|
|
method: string
|
|||
|
|
data?: any
|
|||
|
|
appId: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 系统服务集成层
|
|||
|
|
* 统一管理所有核心服务,提供统一的对外接口
|
|||
|
|
*/
|
|||
|
|
export class SystemServiceIntegration {
|
|||
|
|
private initialized = ref(false)
|
|||
|
|
private running = ref(false)
|
|||
|
|
private config: SystemServiceConfig
|
|||
|
|
private startTime: Date
|
|||
|
|
|
|||
|
|
// 核心服务实例
|
|||
|
|
private eventBus: IEventBuilder<any>
|
|||
|
|
private windowService!: WindowService
|
|||
|
|
private resourceService!: ResourceService
|
|||
|
|
private eventService!: EventCommunicationService
|
|||
|
|
private sandboxEngine!: ApplicationSandboxEngine
|
|||
|
|
private lifecycleManager!: ApplicationLifecycleManager
|
|||
|
|
|
|||
|
|
// 系统状态
|
|||
|
|
private systemStatus = reactive<SystemStatus>({
|
|||
|
|
initialized: false,
|
|||
|
|
running: false,
|
|||
|
|
servicesStatus: {
|
|||
|
|
windowService: false,
|
|||
|
|
resourceService: false,
|
|||
|
|
eventService: false,
|
|||
|
|
sandboxEngine: false,
|
|||
|
|
lifecycleManager: false,
|
|||
|
|
},
|
|||
|
|
performance: {
|
|||
|
|
memoryUsage: 0,
|
|||
|
|
cpuUsage: 0,
|
|||
|
|
activeApps: 0,
|
|||
|
|
activeWindows: 0,
|
|||
|
|
},
|
|||
|
|
uptime: 0,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 性能监控
|
|||
|
|
private cleanupInterval: number | null = null
|
|||
|
|
private performanceInterval: number | null = null
|
|||
|
|
|
|||
|
|
constructor(config: SystemServiceConfig = {}) {
|
|||
|
|
this.config = {
|
|||
|
|
debug: false,
|
|||
|
|
maxMemoryUsage: 1024, // 1GB
|
|||
|
|
maxCpuUsage: 80, // 80%
|
|||
|
|
enablePerformanceMonitoring: true,
|
|||
|
|
enableSecurityAudit: true,
|
|||
|
|
autoCleanup: true,
|
|||
|
|
cleanupInterval: 5 * 60 * 1000, // 5分钟
|
|||
|
|
...config,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.startTime = new Date()
|
|||
|
|
this.eventBus = new EventBuilderImpl()
|
|||
|
|
|
|||
|
|
this.setupGlobalErrorHandling()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化系统服务
|
|||
|
|
*/
|
|||
|
|
async initialize(): Promise<void> {
|
|||
|
|
if (this.initialized.value) {
|
|||
|
|
throw new Error('系统服务已初始化')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
console.log('开始初始化系统服务...')
|
|||
|
|
|
|||
|
|
// 按依赖顺序初始化服务
|
|||
|
|
await this.initializeServices()
|
|||
|
|
|
|||
|
|
// 设置服务间通信
|
|||
|
|
this.setupServiceCommunication()
|
|||
|
|
|
|||
|
|
// 设置SDK消息处理
|
|||
|
|
this.setupSDKMessageHandling()
|
|||
|
|
|
|||
|
|
// 启动性能监控
|
|||
|
|
if (this.config.enablePerformanceMonitoring) {
|
|||
|
|
this.startPerformanceMonitoring()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 启动自动清理
|
|||
|
|
if (this.config.autoCleanup) {
|
|||
|
|
this.startAutoCleanup()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 启动外置应用发现服务
|
|||
|
|
// 注意:外置应用发现服务统一由 SystemServiceIntegration 管理,
|
|||
|
|
// ApplicationLifecycleManager 只负责使用已发现的应用,避免重复启动
|
|||
|
|
console.log('启动外置应用发现服务...')
|
|||
|
|
await externalAppDiscovery.startDiscovery()
|
|||
|
|
|
|||
|
|
this.initialized.value = true
|
|||
|
|
this.running.value = true
|
|||
|
|
this.systemStatus.initialized = true
|
|||
|
|
this.systemStatus.running = true
|
|||
|
|
|
|||
|
|
console.log('系统服务初始化完成')
|
|||
|
|
|
|||
|
|
// 发送系统就绪事件
|
|||
|
|
this.eventService.sendMessage('system', 'system-ready', {
|
|||
|
|
timestamp: new Date(),
|
|||
|
|
services: Object.keys(this.systemStatus.servicesStatus),
|
|||
|
|
})
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('系统服务初始化失败:', error)
|
|||
|
|
this.systemStatus.lastError = error instanceof Error ? error.message : String(error)
|
|||
|
|
throw error
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取系统状态
|
|||
|
|
*/
|
|||
|
|
getSystemStatus(): SystemStatus {
|
|||
|
|
this.updateSystemStatus()
|
|||
|
|
return { ...this.systemStatus }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取窗体服务
|
|||
|
|
*/
|
|||
|
|
getWindowService(): WindowService {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
return this.windowService
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取资源服务
|
|||
|
|
*/
|
|||
|
|
getResourceService(): ResourceService {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
return this.resourceService
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取事件服务
|
|||
|
|
*/
|
|||
|
|
getEventService(): EventCommunicationService {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
return this.eventService
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取沙箱引擎
|
|||
|
|
*/
|
|||
|
|
getSandboxEngine(): ApplicationSandboxEngine {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
return this.sandboxEngine
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取生命周期管理器
|
|||
|
|
*/
|
|||
|
|
getLifecycleManager(): ApplicationLifecycleManager {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
return this.lifecycleManager
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理SDK调用
|
|||
|
|
*/
|
|||
|
|
async handleSDKCall(call: SDKCall): Promise<any> {
|
|||
|
|
this.checkInitialized()
|
|||
|
|
|
|||
|
|
const { requestId, method, data, appId } = call
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
this.debugLog(`处理SDK调用: ${method}`, { appId, data })
|
|||
|
|
|
|||
|
|
const result = await this.executeSDKMethod(method, data, appId)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
data: result,
|
|||
|
|
requestId,
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('SDK调用失败:', error)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
error: error instanceof Error ? error.message : String(error),
|
|||
|
|
requestId,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 重启系统服务
|
|||
|
|
*/
|
|||
|
|
async restart(): Promise<void> {
|
|||
|
|
console.log('重启系统服务...')
|
|||
|
|
|
|||
|
|
await this.shutdown()
|
|||
|
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|||
|
|
await this.initialize()
|
|||
|
|
|
|||
|
|
console.log('系统服务重启完成')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭系统服务
|
|||
|
|
*/
|
|||
|
|
async shutdown(): Promise<void> {
|
|||
|
|
console.log('关闭系统服务...')
|
|||
|
|
|
|||
|
|
this.running.value = false
|
|||
|
|
this.systemStatus.running = false
|
|||
|
|
|
|||
|
|
// 停止定时器
|
|||
|
|
if (this.cleanupInterval) {
|
|||
|
|
clearInterval(this.cleanupInterval)
|
|||
|
|
this.cleanupInterval = null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.performanceInterval) {
|
|||
|
|
clearInterval(this.performanceInterval)
|
|||
|
|
this.performanceInterval = null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 停止外置应用发现服务(由 SystemServiceIntegration 统一管理)
|
|||
|
|
externalAppDiscovery.stopDiscovery()
|
|||
|
|
|
|||
|
|
// 按相反顺序关闭服务
|
|||
|
|
try {
|
|||
|
|
if (this.lifecycleManager) {
|
|||
|
|
// 停止所有运行中的应用
|
|||
|
|
const runningApps = this.lifecycleManager.getRunningApps()
|
|||
|
|
for (const app of runningApps) {
|
|||
|
|
await this.lifecycleManager.stopApp(app.id)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.sandboxEngine) {
|
|||
|
|
this.sandboxEngine.destroy()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.eventService) {
|
|||
|
|
this.eventService.destroy()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.windowService) {
|
|||
|
|
// 关闭所有窗体
|
|||
|
|
const windows = this.windowService.getAllWindows()
|
|||
|
|
for (const window of windows) {
|
|||
|
|
await this.windowService.destroyWindow(window.id)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('关闭服务时发生错误:', error)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.initialized.value = false
|
|||
|
|
this.systemStatus.initialized = false
|
|||
|
|
|
|||
|
|
console.log('系统服务已关闭')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 私有方法
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 初始化所有服务
|
|||
|
|
*/
|
|||
|
|
private async initializeServices(): Promise<void> {
|
|||
|
|
// 1. 初始化资源服务
|
|||
|
|
console.log('初始化资源服务...')
|
|||
|
|
this.resourceService = new ResourceService(this.eventBus)
|
|||
|
|
this.systemStatus.servicesStatus.resourceService = true
|
|||
|
|
|
|||
|
|
// 2. 初始化事件通信服务
|
|||
|
|
console.log('初始化事件通信服务...')
|
|||
|
|
this.eventService = new EventCommunicationService(this.eventBus)
|
|||
|
|
this.systemStatus.servicesStatus.eventService = true
|
|||
|
|
|
|||
|
|
// 3. 初始化窗体服务
|
|||
|
|
console.log('初始化窗体服务...')
|
|||
|
|
this.windowService = new WindowService(this.eventBus)
|
|||
|
|
this.systemStatus.servicesStatus.windowService = true
|
|||
|
|
|
|||
|
|
// 4. 初始化沙箱引擎
|
|||
|
|
console.log('初始化沙箱引擎...')
|
|||
|
|
this.sandboxEngine = new ApplicationSandboxEngine(this.resourceService, this.eventService)
|
|||
|
|
this.systemStatus.servicesStatus.sandboxEngine = true
|
|||
|
|
|
|||
|
|
// 5. 初始化生命周期管理器
|
|||
|
|
console.log('初始化生命周期管理器...')
|
|||
|
|
this.lifecycleManager = new ApplicationLifecycleManager(
|
|||
|
|
this.windowService,
|
|||
|
|
this.resourceService,
|
|||
|
|
this.eventService,
|
|||
|
|
this.sandboxEngine,
|
|||
|
|
)
|
|||
|
|
this.systemStatus.servicesStatus.lifecycleManager = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置服务间通信
|
|||
|
|
*/
|
|||
|
|
private setupServiceCommunication(): void {
|
|||
|
|
// 监听应用生命周期事件
|
|||
|
|
this.eventService.subscribe('system', 'app-lifecycle', (message) => {
|
|||
|
|
this.debugLog('[AppLifecycle] 应用生命周期事件:', message.payload)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 监听窗口状态变化事件
|
|||
|
|
this.eventService.subscribe('system', 'window-state-change', (message) => {
|
|||
|
|
this.debugLog('[WindowState] 窗口状态变化消息已处理:', message.payload)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 监听窗体状态变化(来自 WindowService 的 onStateChange 事件)
|
|||
|
|
this.eventBus.addEventListener(
|
|||
|
|
'onStateChange',
|
|||
|
|
(windowId: string, newState: string, oldState: string) => {
|
|||
|
|
console.log(
|
|||
|
|
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`,
|
|||
|
|
)
|
|||
|
|
this.eventService.sendMessage('system', 'window-state-change', {
|
|||
|
|
windowId,
|
|||
|
|
newState,
|
|||
|
|
oldState,
|
|||
|
|
})
|
|||
|
|
console.log(`[SystemIntegration] 已发送 window-state-change 消息到事件通信服务`)
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 监听窗体关闭事件,自动停止对应的应用
|
|||
|
|
this.eventBus.addEventListener('onClose', async (windowId: string) => {
|
|||
|
|
console.log(`[SystemIntegration] 接收到窗体关闭事件: ${windowId}`)
|
|||
|
|
// 查找对应的应用
|
|||
|
|
const runningApps = this.lifecycleManager.getRunningApps()
|
|||
|
|
for (const app of runningApps) {
|
|||
|
|
if (app.windowId === windowId) {
|
|||
|
|
try {
|
|||
|
|
console.log(`窗口关闭,自动停止应用: ${app.id}`)
|
|||
|
|
await this.lifecycleManager.stopApp(app.id)
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`停止应用 ${app.id} 失败:`, error)
|
|||
|
|
}
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 监听资源配额超出
|
|||
|
|
this.eventBus.addEventListener(
|
|||
|
|
'onResourceQuotaExceeded',
|
|||
|
|
(appId: string, resourceType: string) => {
|
|||
|
|
console.log(`[SystemIntegration] 接收到资源配额超出事件: ${appId} - ${resourceType}`)
|
|||
|
|
this.eventService.sendMessage('system', 'resource-quota-exceeded', {
|
|||
|
|
appId,
|
|||
|
|
resourceType,
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置SDK消息处理
|
|||
|
|
*/
|
|||
|
|
private setupSDKMessageHandling(): void {
|
|||
|
|
// 监听来自iframe的SDK调用
|
|||
|
|
window.addEventListener('message', async (event) => {
|
|||
|
|
const data = event.data
|
|||
|
|
if (!data) return
|
|||
|
|
|
|||
|
|
// 处理安全存储消息
|
|||
|
|
if (data.type?.startsWith('sdk:storage:')) {
|
|||
|
|
await this.handleStorageMessage(event)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理其他SDK调用
|
|||
|
|
if (data.type === 'sdk:call') {
|
|||
|
|
const call: SDKCall = data
|
|||
|
|
const result = await this.handleSDKCall(call)
|
|||
|
|
|
|||
|
|
// 发送响应回iframe
|
|||
|
|
const iframe = this.findIframeBySource(event.source as Window)
|
|||
|
|
if (iframe) {
|
|||
|
|
iframe.contentWindow?.postMessage(
|
|||
|
|
{
|
|||
|
|
type: 'system:response',
|
|||
|
|
...result,
|
|||
|
|
},
|
|||
|
|
'*',
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理安全存储消息
|
|||
|
|
*/
|
|||
|
|
private async handleStorageMessage(event: MessageEvent): Promise<void> {
|
|||
|
|
const { type, requestId, appId, key, value } = event.data
|
|||
|
|
|
|||
|
|
if (!requestId || !appId) {
|
|||
|
|
console.warn('存储消息缺少必需参数')
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证应用权限
|
|||
|
|
const app = this.lifecycleManager.getApp(appId)
|
|||
|
|
if (!app) {
|
|||
|
|
console.warn(`未找到应用: ${appId}`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let result: any = null
|
|||
|
|
let success = false
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
switch (type) {
|
|||
|
|
case 'sdk:storage:get':
|
|||
|
|
result = await this.resourceService.getStorage(appId, key)
|
|||
|
|
success = true
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
case 'sdk:storage:set':
|
|||
|
|
result = await this.resourceService.setStorage(appId, key, value)
|
|||
|
|
success = result === true
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
case 'sdk:storage:remove':
|
|||
|
|
result = await this.resourceService.removeStorage(appId, key)
|
|||
|
|
success = result === true
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
console.warn(`未知的存储操作: ${type}`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('存储操作失败:', error)
|
|||
|
|
success = false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 发送响应回iframe
|
|||
|
|
const iframe = this.findIframeBySource(event.source as Window)
|
|||
|
|
if (iframe?.contentWindow) {
|
|||
|
|
iframe.contentWindow.postMessage(
|
|||
|
|
{
|
|||
|
|
type: 'system:storage-response',
|
|||
|
|
requestId,
|
|||
|
|
result,
|
|||
|
|
success,
|
|||
|
|
},
|
|||
|
|
'*',
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行SDK方法
|
|||
|
|
*/
|
|||
|
|
private async executeSDKMethod(method: string, data: any, appId: string): Promise<any> {
|
|||
|
|
const [service, action] = method.split('.')
|
|||
|
|
|
|||
|
|
switch (service) {
|
|||
|
|
case 'window':
|
|||
|
|
return this.executeWindowMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'storage':
|
|||
|
|
return this.executeStorageMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'network':
|
|||
|
|
return this.executeNetworkMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'events':
|
|||
|
|
return this.executeEventMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'ui':
|
|||
|
|
return this.executeUIMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'system':
|
|||
|
|
return this.executeSystemMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
case 'sdk':
|
|||
|
|
return this.executeSDKMethod(action, data, appId)
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的服务: ${service}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行窗体相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeWindowMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
// 查找应用的窗体
|
|||
|
|
const app = this.lifecycleManager.getApp(appId)
|
|||
|
|
if (!app?.windowId) {
|
|||
|
|
throw new Error('应用窗体不存在')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const windowId = app.windowId
|
|||
|
|
|
|||
|
|
switch (action) {
|
|||
|
|
case 'setTitle':
|
|||
|
|
return this.windowService.setWindowTitle(windowId, data.title)
|
|||
|
|
|
|||
|
|
case 'resize':
|
|||
|
|
return this.windowService.setWindowSize(windowId, data.width, data.height)
|
|||
|
|
|
|||
|
|
case 'move':
|
|||
|
|
// 需要实现窗体移动功能
|
|||
|
|
return true
|
|||
|
|
|
|||
|
|
case 'minimize':
|
|||
|
|
return this.windowService.minimizeWindow(windowId)
|
|||
|
|
|
|||
|
|
case 'maximize':
|
|||
|
|
return this.windowService.maximizeWindow(windowId)
|
|||
|
|
|
|||
|
|
case 'restore':
|
|||
|
|
return this.windowService.restoreWindow(windowId)
|
|||
|
|
|
|||
|
|
case 'close':
|
|||
|
|
return this.lifecycleManager.stopApp(appId)
|
|||
|
|
|
|||
|
|
case 'getState':
|
|||
|
|
const window = this.windowService.getWindow(windowId)
|
|||
|
|
return window?.state
|
|||
|
|
|
|||
|
|
case 'getSize':
|
|||
|
|
const windowInfo = this.windowService.getWindow(windowId)
|
|||
|
|
return {
|
|||
|
|
width: windowInfo?.config.width,
|
|||
|
|
height: windowInfo?.config.height,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的窗体操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行存储相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeStorageMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'set':
|
|||
|
|
return this.resourceService.setStorage(appId, data.key, data.value)
|
|||
|
|
|
|||
|
|
case 'get':
|
|||
|
|
return this.resourceService.getStorage(appId, data.key)
|
|||
|
|
|
|||
|
|
case 'remove':
|
|||
|
|
return this.resourceService.removeStorage(appId, data.key)
|
|||
|
|
|
|||
|
|
case 'clear':
|
|||
|
|
return this.resourceService.clearStorage(appId)
|
|||
|
|
|
|||
|
|
case 'keys':
|
|||
|
|
// 需要实现获取所有键的功能
|
|||
|
|
return []
|
|||
|
|
|
|||
|
|
case 'has':
|
|||
|
|
const value = await this.resourceService.getStorage(appId, data.key)
|
|||
|
|
return value !== null
|
|||
|
|
|
|||
|
|
case 'getStats':
|
|||
|
|
return this.resourceService.getStorageUsage(appId)
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的存储操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行网络相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeNetworkMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'request':
|
|||
|
|
const response = await this.resourceService.makeNetworkRequest(appId, data.url, data.config)
|
|||
|
|
return response
|
|||
|
|
? {
|
|||
|
|
data: await response.text(),
|
|||
|
|
status: response.status,
|
|||
|
|
statusText: response.statusText,
|
|||
|
|
headers: {} as Record<string, string>, // 简化headers处理
|
|||
|
|
url: response.url,
|
|||
|
|
}
|
|||
|
|
: null
|
|||
|
|
|
|||
|
|
case 'isOnline':
|
|||
|
|
return navigator.onLine
|
|||
|
|
|
|||
|
|
case 'getStats':
|
|||
|
|
const requests = this.resourceService.getNetworkRequests(appId)
|
|||
|
|
return {
|
|||
|
|
requestCount: requests.length,
|
|||
|
|
failureCount: requests.filter((r) => r.status && r.status >= 400).length,
|
|||
|
|
averageTime: 0, // 需要实现时间统计
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的网络操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行事件相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeEventMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'emit':
|
|||
|
|
return this.eventService.sendMessage(appId, data.channel, data.data)
|
|||
|
|
|
|||
|
|
case 'on':
|
|||
|
|
return this.eventService.subscribe(appId, data.channel, (message) => {
|
|||
|
|
// 发送事件到应用
|
|||
|
|
const app = this.lifecycleManager.getApp(appId)
|
|||
|
|
if (app?.sandboxId) {
|
|||
|
|
this.sandboxEngine.sendMessage(app.sandboxId, {
|
|||
|
|
type: 'system:event',
|
|||
|
|
subscriptionId: data.subscriptionId,
|
|||
|
|
message,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
case 'off':
|
|||
|
|
return this.eventService.unsubscribe(data.subscriptionId)
|
|||
|
|
|
|||
|
|
case 'broadcast':
|
|||
|
|
return this.eventService.broadcast(appId, data.channel, data.data)
|
|||
|
|
|
|||
|
|
case 'sendTo':
|
|||
|
|
return this.eventService.sendCrossAppMessage(appId, data.targetAppId, data.data)
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的事件操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行UI相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeUIMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'showNotification':
|
|||
|
|
return this.resourceService.showNotification(appId, data.title, data)
|
|||
|
|
|
|||
|
|
case 'showToast':
|
|||
|
|
// 需要实现Toast功能
|
|||
|
|
console.log(`[Toast] ${data.message}`)
|
|||
|
|
return 'toast-' + Date.now()
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的UI操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行系统相关方法
|
|||
|
|
*/
|
|||
|
|
private async executeSystemMethod(action: string, data: any, appId: string): Promise<any> {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'getSystemInfo':
|
|||
|
|
return {
|
|||
|
|
platform: navigator.platform,
|
|||
|
|
userAgent: navigator.userAgent,
|
|||
|
|
language: navigator.language,
|
|||
|
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|||
|
|
screenResolution: {
|
|||
|
|
width: screen.width,
|
|||
|
|
height: screen.height,
|
|||
|
|
},
|
|||
|
|
colorDepth: screen.colorDepth,
|
|||
|
|
pixelRatio: window.devicePixelRatio,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'getAppInfo':
|
|||
|
|
const app = this.lifecycleManager.getApp(appId)
|
|||
|
|
return app
|
|||
|
|
? {
|
|||
|
|
id: app.id,
|
|||
|
|
name: app.manifest.name,
|
|||
|
|
version: app.version,
|
|||
|
|
permissions: app.manifest.permissions,
|
|||
|
|
createdAt: app.installedAt,
|
|||
|
|
lastActiveAt: app.lastActiveAt,
|
|||
|
|
}
|
|||
|
|
: null
|
|||
|
|
|
|||
|
|
case 'getClipboard':
|
|||
|
|
return this.resourceService.getClipboard(appId)
|
|||
|
|
|
|||
|
|
case 'setClipboard':
|
|||
|
|
return this.resourceService.setClipboard(appId, data.text)
|
|||
|
|
|
|||
|
|
case 'getCurrentTime':
|
|||
|
|
return new Date()
|
|||
|
|
|
|||
|
|
case 'generateUUID':
|
|||
|
|
return crypto.randomUUID()
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
throw new Error(`未知的系统操作: ${action}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 查找消息来源的iframe
|
|||
|
|
*/
|
|||
|
|
private findIframeBySource(source: Window): HTMLIFrameElement | null {
|
|||
|
|
const iframes = Array.from(document.querySelectorAll('iframe'))
|
|||
|
|
|
|||
|
|
for (const iframe of iframes) {
|
|||
|
|
if (iframe.contentWindow === source) {
|
|||
|
|
return iframe
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 开始性能监控
|
|||
|
|
*/
|
|||
|
|
private startPerformanceMonitoring(): void {
|
|||
|
|
this.performanceInterval = setInterval(() => {
|
|||
|
|
this.updateSystemStatus()
|
|||
|
|
|
|||
|
|
// 检查性能阈值
|
|||
|
|
if (this.systemStatus.performance.memoryUsage > this.config.maxMemoryUsage!) {
|
|||
|
|
this.eventService.sendMessage('system', 'performance-alert', {
|
|||
|
|
type: 'memory',
|
|||
|
|
usage: this.systemStatus.performance.memoryUsage,
|
|||
|
|
limit: this.config.maxMemoryUsage,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.systemStatus.performance.cpuUsage > this.config.maxCpuUsage!) {
|
|||
|
|
this.eventService.sendMessage('system', 'performance-alert', {
|
|||
|
|
type: 'cpu',
|
|||
|
|
usage: this.systemStatus.performance.cpuUsage,
|
|||
|
|
limit: this.config.maxCpuUsage,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}, 10000) // 每10秒检查一次
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 开始自动清理
|
|||
|
|
*/
|
|||
|
|
private startAutoCleanup(): void {
|
|||
|
|
this.cleanupInterval = setInterval(() => {
|
|||
|
|
this.debugLog('执行自动清理...')
|
|||
|
|
|
|||
|
|
// 清理事件服务
|
|||
|
|
this.eventService.cleanup()
|
|||
|
|
|
|||
|
|
// 清理沙箱引擎缓存
|
|||
|
|
// this.sandboxEngine.cleanup()
|
|||
|
|
|
|||
|
|
this.debugLog('自动清理完成')
|
|||
|
|
}, this.config.cleanupInterval!)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新系统状态
|
|||
|
|
*/
|
|||
|
|
private updateSystemStatus(): void {
|
|||
|
|
this.systemStatus.uptime = Date.now() - this.startTime.getTime()
|
|||
|
|
this.systemStatus.performance.activeApps = this.lifecycleManager?.getRunningApps().length || 0
|
|||
|
|
this.systemStatus.performance.activeWindows = this.windowService?.getAllWindows().length || 0
|
|||
|
|
|
|||
|
|
// 简化的内存和CPU使用率计算
|
|||
|
|
this.systemStatus.performance.memoryUsage =
|
|||
|
|
(performance as any).memory?.usedJSHeapSize / 1024 / 1024 || 0
|
|||
|
|
this.systemStatus.performance.cpuUsage = Math.random() * 20 // 模拟CPU使用率
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查是否已初始化
|
|||
|
|
*/
|
|||
|
|
private checkInitialized(): void {
|
|||
|
|
if (!this.initialized.value) {
|
|||
|
|
throw new Error('系统服务未初始化')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置全局错误处理
|
|||
|
|
*/
|
|||
|
|
private setupGlobalErrorHandling(): void {
|
|||
|
|
window.addEventListener('error', (event) => {
|
|||
|
|
console.error('全局错误:', event.error)
|
|||
|
|
this.systemStatus.lastError = event.error?.message || '未知错误'
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
window.addEventListener('unhandledrejection', (event) => {
|
|||
|
|
console.error('未处理的Promise拒绝:', event.reason)
|
|||
|
|
this.systemStatus.lastError = event.reason?.message || '未处理的Promise拒绝'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 调试日志
|
|||
|
|
*/
|
|||
|
|
private debugLog(message: string, data?: any): void {
|
|||
|
|
if (this.config.debug) {
|
|||
|
|
console.log(`[SystemService] ${message}`, data)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|