11
This commit is contained in:
@@ -14,9 +14,7 @@ registerBuiltInApps()
|
||||
|
||||
// 初始化系统服务
|
||||
const systemService = new SystemServiceIntegration({
|
||||
debug: import.meta.env.DEV,
|
||||
enablePerformanceMonitoring: true,
|
||||
enableSecurityAudit: true
|
||||
debug: import.meta.env.DEV
|
||||
})
|
||||
|
||||
// 创建应用实例
|
||||
|
||||
@@ -20,7 +20,7 @@ export enum AppLifecycleState {
|
||||
UNINSTALLING = 'uninstalling',
|
||||
ERROR = 'error',
|
||||
CRASHED = 'crashed',
|
||||
AVAILABLE = 'available', // 外置应用可用但未注册状态
|
||||
AVAILABLE = 'available' // 外置应用可用但未注册状态
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,16 +81,6 @@ export interface AppInstance {
|
||||
persistent: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用安装包接口
|
||||
*/
|
||||
export interface AppPackage {
|
||||
manifest: AppManifest
|
||||
files: Map<string, Blob | string> // 文件路径到内容的映射
|
||||
signature?: string // 数字签名
|
||||
checksum: string // 校验和
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用启动选项
|
||||
*/
|
||||
@@ -138,7 +128,7 @@ export class ApplicationLifecycleManager {
|
||||
windowService: WindowService,
|
||||
resourceService: ResourceService,
|
||||
eventService: EventCommunicationService,
|
||||
sandboxEngine: ApplicationSandboxEngine,
|
||||
sandboxEngine: ApplicationSandboxEngine
|
||||
) {
|
||||
this.windowService = windowService
|
||||
this.resourceService = resourceService
|
||||
@@ -146,122 +136,6 @@ export class ApplicationLifecycleManager {
|
||||
this.sandboxEngine = sandboxEngine
|
||||
|
||||
this.setupEventListeners()
|
||||
this.loadInstalledApps()
|
||||
// 外部应用发现已由 SystemServiceIntegration 统一管理,无需重复初始化
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装应用
|
||||
*/
|
||||
async installApp(appPackage: AppPackage): Promise<string> {
|
||||
const { manifest, files, checksum } = appPackage
|
||||
const appId = manifest.id
|
||||
|
||||
try {
|
||||
// 检查应用是否已安装
|
||||
if (this.installedApps.has(appId)) {
|
||||
throw new Error(`应用 ${appId} 已安装`)
|
||||
}
|
||||
|
||||
// 验证清单文件
|
||||
this.validateManifest(manifest)
|
||||
|
||||
// 验证校验和
|
||||
if (!this.verifyChecksum(files, checksum)) {
|
||||
throw new Error('应用包校验失败')
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
await this.checkPermissions(manifest.permissions)
|
||||
|
||||
const now = new Date()
|
||||
const appInstance: AppInstance = {
|
||||
id: appId,
|
||||
manifest,
|
||||
state: AppLifecycleState.INSTALLING,
|
||||
processId: '',
|
||||
installedAt: now,
|
||||
errorCount: 0,
|
||||
crashCount: 0,
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
version: manifest.version,
|
||||
autoStart: false,
|
||||
persistent: manifest.background?.persistent || false,
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
this.updateAppState(appInstance, AppLifecycleState.INSTALLING)
|
||||
this.installedApps.set(appId, appInstance)
|
||||
|
||||
// 存储应用文件
|
||||
this.appFiles.set(appId, files)
|
||||
|
||||
// 保存到本地存储
|
||||
await this.saveAppToStorage(appInstance)
|
||||
|
||||
// 更新状态为已安装
|
||||
this.updateAppState(appInstance, AppLifecycleState.INSTALLED)
|
||||
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'installed',
|
||||
appId,
|
||||
manifest,
|
||||
})
|
||||
|
||||
console.log(`应用 ${manifest.name} (${appId}) 安装成功`)
|
||||
return appId
|
||||
} catch (error) {
|
||||
// 清理安装失败的应用
|
||||
this.installedApps.delete(appId)
|
||||
this.appFiles.delete(appId)
|
||||
|
||||
console.error('应用安装失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载应用
|
||||
*/
|
||||
async uninstallApp(appId: string): Promise<boolean> {
|
||||
const app = this.installedApps.get(appId)
|
||||
if (!app) {
|
||||
throw new Error(`应用 ${appId} 未安装`)
|
||||
}
|
||||
|
||||
try {
|
||||
// 如果应用正在运行,先停止
|
||||
if (app.state === AppLifecycleState.RUNNING || app.state === AppLifecycleState.SUSPENDED) {
|
||||
await this.stopApp(appId)
|
||||
}
|
||||
|
||||
this.updateAppState(app, AppLifecycleState.UNINSTALLING)
|
||||
|
||||
// 清理应用数据
|
||||
await this.resourceService.clearStorage(appId)
|
||||
await this.resourceService.revokeAllPermissions(appId)
|
||||
|
||||
// 删除应用文件
|
||||
this.appFiles.delete(appId)
|
||||
|
||||
// 从存储中删除
|
||||
await this.removeAppFromStorage(appId)
|
||||
|
||||
// 从已安装列表中移除
|
||||
this.installedApps.delete(appId)
|
||||
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'uninstalled',
|
||||
appId,
|
||||
})
|
||||
|
||||
console.log(`应用 ${appId} 卸载成功`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('应用卸载失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,6 +144,8 @@ export class ApplicationLifecycleManager {
|
||||
async startApp(appId: string, options: AppStartOptions = {}): Promise<string> {
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
console.log('-----------------------------')
|
||||
|
||||
// 如果应用未安装,检查是否为外置应用
|
||||
let isExternalApp = false
|
||||
if (!app) {
|
||||
@@ -292,7 +168,7 @@ export class ApplicationLifecycleManager {
|
||||
cpuUsage: 0,
|
||||
version: externalApp.manifest.version,
|
||||
autoStart: false,
|
||||
persistent: false,
|
||||
persistent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,21 +188,7 @@ export class ApplicationLifecycleManager {
|
||||
this.updateAppState(app, AppLifecycleState.STARTING)
|
||||
|
||||
// 检查是否为内置应用
|
||||
let isBuiltInApp = false
|
||||
|
||||
try {
|
||||
const { AppRegistry } = await import('../apps/AppRegistry')
|
||||
const appRegistry = AppRegistry.getInstance()
|
||||
isBuiltInApp = appRegistry.hasApp(appId)
|
||||
} catch (error) {
|
||||
console.warn('无法导入 AppRegistry')
|
||||
}
|
||||
|
||||
// 检查是否为外置应用(仅当不是内置应用时)
|
||||
// 修复:移除重复的变量声明,使用已声明的isExternalApp变量
|
||||
if (!isBuiltInApp && !isExternalApp) {
|
||||
isExternalApp = externalAppDiscovery.hasApp(appId)
|
||||
}
|
||||
let isBuiltInApp = true
|
||||
|
||||
// 创建窗体(如果不是后台应用)
|
||||
let windowId: string | undefined
|
||||
@@ -341,23 +203,12 @@ export class ApplicationLifecycleManager {
|
||||
minWidth: app.manifest.window?.minWidth,
|
||||
minHeight: app.manifest.window?.minHeight,
|
||||
maxWidth: app.manifest.window?.maxWidth,
|
||||
maxHeight: app.manifest.window?.maxHeight,
|
||||
maxHeight: app.manifest.window?.maxHeight
|
||||
}
|
||||
|
||||
const windowInstance = await this.windowService.createWindow(appId, windowConfig)
|
||||
windowId = windowInstance.id
|
||||
app.windowId = windowId
|
||||
|
||||
// 对于内置应用,需要在窗口内容区域挂载 AppRenderer 组件
|
||||
if (isBuiltInApp) {
|
||||
await this.mountBuiltInApp(appId, windowInstance)
|
||||
}
|
||||
|
||||
// 对于内置应用,不需要等待窗口DOM元素渲染
|
||||
if (!isBuiltInApp) {
|
||||
// 稍等片刻确保窗口DOM元素已经渲染完成
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
}
|
||||
}
|
||||
|
||||
// 对于外置应用,需要创建沙箱;内置应用跳过沙箱
|
||||
@@ -371,13 +222,13 @@ export class ApplicationLifecycleManager {
|
||||
networkTimeout: 15000, // 增加超时时间到15秒
|
||||
csp:
|
||||
app.manifest.contentSecurity?.policy ||
|
||||
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self';",
|
||||
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self';"
|
||||
}
|
||||
|
||||
const sandbox = await this.sandboxEngine.createSandbox(
|
||||
appId,
|
||||
windowId || 'background',
|
||||
sandboxConfig,
|
||||
sandboxConfig
|
||||
)
|
||||
app.sandboxId = sandbox.id
|
||||
|
||||
@@ -474,105 +325,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停应用
|
||||
*/
|
||||
async suspendApp(appId: string): Promise<boolean> {
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!app || app.state !== AppLifecycleState.RUNNING) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
// 暂停沙箱
|
||||
if (app.sandboxId) {
|
||||
this.sandboxEngine.suspendSandbox(app.sandboxId)
|
||||
}
|
||||
|
||||
// 最小化窗体
|
||||
if (app.windowId) {
|
||||
this.windowService.minimizeWindow(app.windowId)
|
||||
}
|
||||
|
||||
this.updateAppState(app, AppLifecycleState.SUSPENDED)
|
||||
|
||||
// 注意:状态变更消息由updateAppState方法自动发送,不需要手动发送
|
||||
|
||||
console.log(`应用 ${appId} 已暂停`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('应用暂停失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复应用
|
||||
*/
|
||||
async resumeApp(appId: string): Promise<boolean> {
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!app || app.state !== AppLifecycleState.SUSPENDED) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
// 恢复沙箱
|
||||
if (app.sandboxId) {
|
||||
this.sandboxEngine.resumeSandbox(app.sandboxId)
|
||||
}
|
||||
|
||||
// 恢复窗体
|
||||
if (app.windowId) {
|
||||
this.windowService.restoreWindow(app.windowId)
|
||||
}
|
||||
|
||||
app.lastActiveAt = new Date()
|
||||
this.updateAppState(app, AppLifecycleState.RUNNING)
|
||||
|
||||
// 注意:状态变更消息由updateAppState方法自动发送,不需要手动发送
|
||||
|
||||
console.log(`应用 ${appId} 已恢复`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('应用恢复失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启应用
|
||||
*/
|
||||
async restartApp(appId: string, options?: AppStartOptions): Promise<string> {
|
||||
await this.stopApp(appId)
|
||||
// 等待一小段时间确保完全停止
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
return this.startApp(appId, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用信息
|
||||
*/
|
||||
@@ -629,7 +381,7 @@ export class ApplicationLifecycleManager {
|
||||
cpuUsage: app.cpuUsage,
|
||||
startedAt: app.startedAt,
|
||||
lastActiveAt: app.lastActiveAt,
|
||||
uptime: app.startedAt ? Date.now() - app.startedAt.getTime() : 0,
|
||||
uptime: app.startedAt ? Date.now() - app.startedAt.getTime() : 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,9 +398,11 @@ export class ApplicationLifecycleManager {
|
||||
|
||||
console.log(`[LifecycleManager] 为内置应用 ${appId} 创建 AppRenderer 组件`)
|
||||
|
||||
console.log('----------------------------------')
|
||||
|
||||
const app = createApp({
|
||||
components: { AppRenderer },
|
||||
template: `<AppRenderer :app-id="'${appId}'" :window-id="'${windowInstance.id}'"/>`,
|
||||
template: `<AppRenderer :app-id="'${appId}'" :window-id="'${windowInstance.id}'"/>`
|
||||
})
|
||||
|
||||
// 提供系统服务(使用当前实例所在的系统服务)
|
||||
@@ -657,7 +411,7 @@ export class ApplicationLifecycleManager {
|
||||
getResourceService: () => this.resourceService,
|
||||
getEventService: () => this.eventService,
|
||||
getSandboxEngine: () => this.sandboxEngine,
|
||||
getLifecycleManager: () => this,
|
||||
getLifecycleManager: () => this
|
||||
})
|
||||
|
||||
// 挂载到窗口内容区域
|
||||
@@ -674,66 +428,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证应用清单文件
|
||||
*/
|
||||
private validateManifest(manifest: AppManifest): void {
|
||||
const required = ['id', 'name', 'version', 'entryPoint']
|
||||
|
||||
for (const field of required) {
|
||||
if (!manifest[field as keyof AppManifest]) {
|
||||
throw new Error(`清单文件缺少必需字段: ${field}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 验证版本格式
|
||||
if (!/^\d+\.\d+\.\d+/.test(manifest.version)) {
|
||||
throw new Error('版本号格式不正确,应为 x.y.z 格式')
|
||||
}
|
||||
|
||||
// 验证应用ID格式
|
||||
if (!/^[a-zA-Z0-9._-]+$/.test(manifest.id)) {
|
||||
throw new Error('应用ID格式不正确')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证校验和
|
||||
*/
|
||||
private verifyChecksum(files: Map<string, Blob | string>, expectedChecksum: string): boolean {
|
||||
// 简化实现,实际应用中应使用更强的哈希算法
|
||||
let content = ''
|
||||
for (const [path, data] of files.entries()) {
|
||||
content += path + (typeof data === 'string' ? data : data.size)
|
||||
}
|
||||
|
||||
const actualChecksum = this.safeBase64Encode(content).slice(0, 32)
|
||||
return actualChecksum === expectedChecksum
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的 Base64 编码,支持 Unicode 字符
|
||||
*/
|
||||
private safeBase64Encode(str: string): string {
|
||||
try {
|
||||
// 使用 encodeURIComponent + atob 来处理 Unicode 字符
|
||||
return btoa(
|
||||
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) {
|
||||
return String.fromCharCode(parseInt(p1, 16))
|
||||
}),
|
||||
)
|
||||
} catch (error) {
|
||||
// 如果还是失败,使用简单的哈希算法
|
||||
let hash = 0
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i)
|
||||
hash = (hash << 5) - hash + char
|
||||
hash = hash & hash // 转换为32位整数
|
||||
}
|
||||
return Math.abs(hash).toString(36)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限
|
||||
*/
|
||||
@@ -745,115 +439,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在沙箱中加载应用
|
||||
*/
|
||||
private async loadAppInSandbox(app: AppInstance, sandboxId: string): Promise<void> {
|
||||
const appFiles = this.appFiles.get(app.id)
|
||||
if (!appFiles) {
|
||||
throw new Error('应用文件不存在')
|
||||
}
|
||||
|
||||
const entryFile = appFiles.get(app.manifest.entryPoint)
|
||||
if (!entryFile) {
|
||||
throw new Error('入口文件不存在')
|
||||
}
|
||||
|
||||
// 创建应用URL
|
||||
const entryUrl = this.createAppUrl(app.id, app.manifest.entryPoint, entryFile)
|
||||
|
||||
// 在沙箱中加载应用
|
||||
await this.sandboxEngine.loadApplication(sandboxId, entryUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建应用文件URL
|
||||
*/
|
||||
private createAppUrl(appId: string, filePath: string, content: Blob | string): string {
|
||||
let blob: Blob
|
||||
|
||||
if (typeof content === 'string') {
|
||||
// 确保使用UTF-8编码创建Blob
|
||||
const contentType = this.getContentType(filePath)
|
||||
const utf8ContentType = contentType.includes('charset')
|
||||
? contentType
|
||||
: `${contentType}; charset=utf-8`
|
||||
blob = new Blob([content], { type: utf8ContentType })
|
||||
} else {
|
||||
blob = content
|
||||
}
|
||||
|
||||
return URL.createObjectURL(blob)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件内容类型
|
||||
*/
|
||||
private getContentType(filePath: string): string {
|
||||
const ext = filePath.split('.').pop()?.toLowerCase()
|
||||
|
||||
switch (ext) {
|
||||
case 'html':
|
||||
return 'text/html; charset=utf-8'
|
||||
case 'js':
|
||||
return 'application/javascript; charset=utf-8'
|
||||
case 'css':
|
||||
return 'text/css; charset=utf-8'
|
||||
case 'json':
|
||||
return 'application/json; charset=utf-8'
|
||||
case 'png':
|
||||
return 'image/png'
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
return 'image/jpeg'
|
||||
case 'svg':
|
||||
return 'image/svg+xml; charset=utf-8'
|
||||
default:
|
||||
return 'text/plain; charset=utf-8'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存应用到存储
|
||||
*/
|
||||
private async saveAppToStorage(app: AppInstance): Promise<void> {
|
||||
const appData = {
|
||||
id: app.id,
|
||||
manifest: app.manifest,
|
||||
installedAt: app.installedAt.toISOString(),
|
||||
version: app.version,
|
||||
autoStart: app.autoStart,
|
||||
persistent: app.persistent,
|
||||
}
|
||||
|
||||
await this.resourceService.setStorage('system', `apps.${app.id}`, appData)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从存储中删除应用
|
||||
*/
|
||||
private async removeAppFromStorage(appId: string): Promise<void> {
|
||||
await this.resourceService.removeStorage('system', `apps.${appId}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化外置应用发现(已由 SystemServiceIntegration 统一管理)
|
||||
* 这个方法保留用于未来可能的扩展,但不再重复启动发现服务
|
||||
*/
|
||||
private async initializeExternalAppDiscovery(): Promise<void> {
|
||||
try {
|
||||
console.log('[LifecycleManager] 外置应用发现服务已由系统服务集成统一管理')
|
||||
|
||||
// 可以在这里添加应用生命周期管理器特有的外置应用监听逻辑
|
||||
// 例如监听外置应用的注册/卸载事件
|
||||
} catch (error) {
|
||||
console.error('[LifecycleManager] 初始化外置应用监听失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 已移除:外部应用不再需要注册到 installedApps 中
|
||||
// 外部应用在启动时会创建临时实例
|
||||
|
||||
/**
|
||||
* 为外置应用加载代码到沙箱
|
||||
*/
|
||||
@@ -904,7 +489,7 @@ export class ApplicationLifecycleManager {
|
||||
version: externalApp.manifest.version,
|
||||
autoStart: false,
|
||||
persistent: false,
|
||||
isExternal: true,
|
||||
isExternal: true
|
||||
}
|
||||
apps.push(appInstance)
|
||||
}
|
||||
@@ -925,42 +510,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载已安装的应用
|
||||
*/
|
||||
private async loadInstalledApps(): Promise<void> {
|
||||
try {
|
||||
// 从存储中加载应用列表
|
||||
const appsData = (await this.resourceService.getStorage('system', 'apps')) || {}
|
||||
|
||||
for (const [appId, appData] of Object.entries(appsData as Record<string, any>)) {
|
||||
if (appData && typeof appData === 'object') {
|
||||
const app: AppInstance = {
|
||||
id: appId,
|
||||
manifest: appData.manifest,
|
||||
state: AppLifecycleState.STOPPED,
|
||||
processId: '',
|
||||
installedAt: new Date(appData.installedAt),
|
||||
errorCount: 0,
|
||||
crashCount: 0,
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
version: appData.version,
|
||||
autoStart: appData.autoStart || false,
|
||||
persistent: appData.persistent || false,
|
||||
}
|
||||
|
||||
this.updateAppState(app, AppLifecycleState.INSTALLED)
|
||||
this.installedApps.set(appId, app)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`已加载 ${this.installedApps.size} 个已安装应用`)
|
||||
} catch (error) {
|
||||
console.error('加载已安装应用失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件监听器
|
||||
*/
|
||||
@@ -981,24 +530,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 监听性能告警
|
||||
this.eventService.subscribe('system', 'performance-alert', (message) => {
|
||||
const { sandboxId, type, usage, limit } = message.payload
|
||||
|
||||
for (const app of this.installedApps.values()) {
|
||||
if (app.sandboxId === sandboxId) {
|
||||
if (type === 'memory') {
|
||||
app.memoryUsage = usage
|
||||
} else if (type === 'cpu') {
|
||||
app.cpuUsage = usage
|
||||
}
|
||||
|
||||
console.warn(`应用 ${app.id} ${type} 使用量 ${usage} 超过限制 ${limit}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1013,7 +544,7 @@ export class ApplicationLifecycleManager {
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'error',
|
||||
appId,
|
||||
error: error.message,
|
||||
error: error.message
|
||||
})
|
||||
|
||||
console.error(`应用 ${appId} 发生错误:`, error)
|
||||
@@ -1050,7 +581,7 @@ export class ApplicationLifecycleManager {
|
||||
type: 'stateChanged',
|
||||
appId: app.id,
|
||||
newState,
|
||||
oldState,
|
||||
oldState
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +109,7 @@ export class ApplicationSandboxEngine {
|
||||
private resourceService: ResourceService
|
||||
private eventService: EventCommunicationService
|
||||
|
||||
constructor(
|
||||
resourceService: ResourceService,
|
||||
eventService: EventCommunicationService
|
||||
) {
|
||||
constructor(resourceService: ResourceService, eventService: EventCommunicationService) {
|
||||
this.resourceService = resourceService
|
||||
this.eventService = eventService
|
||||
this.startPerformanceMonitoring()
|
||||
@@ -180,7 +177,6 @@ export class ApplicationSandboxEngine {
|
||||
|
||||
console.log(`沙箱 ${sandboxId} 创建成功`)
|
||||
return sandbox
|
||||
|
||||
} catch (error) {
|
||||
this.updateSandboxState(sandbox, SandboxState.ERROR)
|
||||
sandbox.errors.push(error instanceof Error ? error.message : String(error))
|
||||
@@ -216,7 +212,9 @@ export class ApplicationSandboxEngine {
|
||||
// 等待加载完成
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeoutId = setTimeout(() => {
|
||||
console.error(`应用加载超时: ${sandbox.appId}, URL: ${applicationUrl}, 超时时间: ${sandbox.config.networkTimeout}ms`)
|
||||
console.error(
|
||||
`应用加载超时: ${sandbox.appId}, URL: ${applicationUrl}, 超时时间: ${sandbox.config.networkTimeout}ms`
|
||||
)
|
||||
reject(new Error('应用加载超时'))
|
||||
}, sandbox.config.networkTimeout)
|
||||
|
||||
@@ -251,64 +249,6 @@ export class ApplicationSandboxEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停沙箱
|
||||
*/
|
||||
suspendSandbox(sandboxId: string): boolean {
|
||||
const sandbox = this.sandboxes.get(sandboxId)
|
||||
if (!sandbox || sandbox.state !== SandboxState.RUNNING) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
this.updateSandboxState(sandbox, SandboxState.SUSPENDED)
|
||||
|
||||
if (sandbox.iframe) {
|
||||
// 暂停iframe中的脚本执行
|
||||
const iframeWindow = sandbox.iframe.contentWindow
|
||||
if (iframeWindow) {
|
||||
// 发送暂停事件到应用
|
||||
iframeWindow.postMessage({ type: 'system:suspend' }, '*')
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`沙箱 ${sandboxId} 已暂停`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('暂停沙箱失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复沙箱
|
||||
*/
|
||||
resumeSandbox(sandboxId: string): boolean {
|
||||
const sandbox = this.sandboxes.get(sandboxId)
|
||||
if (!sandbox || sandbox.state !== SandboxState.SUSPENDED) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
this.updateSandboxState(sandbox, SandboxState.RUNNING)
|
||||
sandbox.lastActiveAt = new Date()
|
||||
|
||||
if (sandbox.iframe) {
|
||||
const iframeWindow = sandbox.iframe.contentWindow
|
||||
if (iframeWindow) {
|
||||
// 发送恢复事件到应用
|
||||
iframeWindow.postMessage({ type: 'system:resume' }, '*')
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`沙箱 ${sandboxId} 已恢复`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('恢复沙箱失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁沙箱
|
||||
*/
|
||||
@@ -323,8 +263,8 @@ export class ApplicationSandboxEngine {
|
||||
|
||||
// 移除消息事件监听器
|
||||
if (sandbox.messageHandler) {
|
||||
window.removeEventListener('message', sandbox.messageHandler);
|
||||
sandbox.messageHandler = undefined;
|
||||
window.removeEventListener('message', sandbox.messageHandler)
|
||||
sandbox.messageHandler = undefined
|
||||
}
|
||||
|
||||
// 清理DOM元素
|
||||
@@ -366,7 +306,7 @@ export class ApplicationSandboxEngine {
|
||||
* 获取应用的所有沙箱
|
||||
*/
|
||||
getAppSandboxes(appId: string): SandboxInstance[] {
|
||||
return Array.from(this.sandboxes.values()).filter(sandbox => sandbox.appId === appId)
|
||||
return Array.from(this.sandboxes.values()).filter((sandbox) => sandbox.appId === appId)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -632,10 +572,10 @@ export class ApplicationSandboxEngine {
|
||||
if (event.source === sandbox.iframe!.contentWindow) {
|
||||
this.handleSandboxMessage(sandbox, event.data)
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', messageHandler);
|
||||
}
|
||||
window.addEventListener('message', messageHandler)
|
||||
// 存储事件监听器引用,以便在销毁时移除
|
||||
sandbox.messageHandler = messageHandler;
|
||||
sandbox.messageHandler = messageHandler
|
||||
|
||||
// 简化安全限制,主要依赖iframe的sandbox属性
|
||||
sandbox.iframe.addEventListener('load', () => {
|
||||
@@ -709,7 +649,11 @@ export class ApplicationSandboxEngine {
|
||||
break
|
||||
|
||||
case 'network':
|
||||
result = await this.resourceService.makeNetworkRequest(sandbox.appId, data.url, data.options)
|
||||
result = await this.resourceService.makeNetworkRequest(
|
||||
sandbox.appId,
|
||||
data.url,
|
||||
data.options
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -1171,10 +1115,10 @@ export class ApplicationSandboxEngine {
|
||||
// 通知系统应用已准备就绪
|
||||
window.parent.postMessage({ type: 'app:ready' }, '*');
|
||||
})();
|
||||
`;
|
||||
`
|
||||
|
||||
iframeDoc.head.appendChild(script)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置性能监控
|
||||
@@ -1260,9 +1204,12 @@ export class ApplicationSandboxEngine {
|
||||
private collectPerformanceMetrics(sandbox: SandboxInstance): void {
|
||||
if (sandbox.iframe && sandbox.iframe.contentWindow) {
|
||||
// 请求性能数据
|
||||
sandbox.iframe.contentWindow.postMessage({
|
||||
sandbox.iframe.contentWindow.postMessage(
|
||||
{
|
||||
type: 'system:performance-request'
|
||||
}, '*')
|
||||
},
|
||||
'*'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,49 +8,75 @@ import type { ResourceType } from './ResourceService'
|
||||
* 消息类型枚举
|
||||
*/
|
||||
export enum MessageType {
|
||||
/** 系统事件 */
|
||||
SYSTEM = 'system',
|
||||
/** 应用事件 */
|
||||
APPLICATION = 'application',
|
||||
/** 用户交互事件 */
|
||||
USER_INTERACTION = 'user_interaction',
|
||||
/** 跨应用事件 */
|
||||
CROSS_APP = 'cross_app',
|
||||
BROADCAST = 'broadcast',
|
||||
/** 广播事件 */
|
||||
BROADCAST = 'broadcast'
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息优先级枚举
|
||||
*/
|
||||
export enum MessagePriority {
|
||||
/** 低优先级 */
|
||||
LOW = 0,
|
||||
/** 正常优先级 */
|
||||
NORMAL = 1,
|
||||
/** 高优先级 */
|
||||
HIGH = 2,
|
||||
CRITICAL = 3,
|
||||
/** 紧急优先级 */
|
||||
CRITICAL = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息状态枚举
|
||||
*/
|
||||
export enum MessageStatus {
|
||||
/** 等待发送 */
|
||||
PENDING = 'pending',
|
||||
/** 已发送 */
|
||||
SENT = 'sent',
|
||||
/** 已送达 */
|
||||
DELIVERED = 'delivered',
|
||||
/** 发送失败 */
|
||||
FAILED = 'failed',
|
||||
EXPIRED = 'expired',
|
||||
/** 已取消 */
|
||||
EXPIRED = 'expired'
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件消息接口
|
||||
*/
|
||||
export interface EventMessage {
|
||||
/** 消息ID */
|
||||
id: string
|
||||
/** 消息类型 */
|
||||
type: MessageType
|
||||
/** 消息优先级 */
|
||||
priority: MessagePriority
|
||||
/** 发送者ID */
|
||||
senderId: string
|
||||
receiverId?: string // undefined表示广播消息
|
||||
/** 接收者ID, undefined表示广播消息 */
|
||||
receiverId?: string
|
||||
/** 消息频道 */
|
||||
channel: string
|
||||
/** 消息内容 */
|
||||
payload: any
|
||||
/** 消息发送时间 */
|
||||
timestamp: Date
|
||||
/** 消息过期时间 */
|
||||
expiresAt?: Date
|
||||
/** 消息状态 */
|
||||
status: MessageStatus
|
||||
/** 重试次数 */
|
||||
retryCount: number
|
||||
/** 最大重试次数 */
|
||||
maxRetries: number
|
||||
}
|
||||
|
||||
@@ -58,13 +84,21 @@ export interface EventMessage {
|
||||
* 事件订阅者接口
|
||||
*/
|
||||
export interface EventSubscriber {
|
||||
/** 订阅者ID */
|
||||
id: string
|
||||
/** 应用ID */
|
||||
appId: string
|
||||
/** 消息频道 */
|
||||
channel: string
|
||||
/** 订阅者处理函数 */
|
||||
handler: (message: EventMessage) => void | Promise<void>
|
||||
/** 消息过滤器 */
|
||||
filter?: (message: EventMessage) => boolean
|
||||
/** 订阅者优先级 */
|
||||
priority: MessagePriority
|
||||
/** 创建时间 */
|
||||
createdAt: Date
|
||||
/** 是否启用 */
|
||||
active: boolean
|
||||
}
|
||||
|
||||
@@ -72,23 +106,36 @@ export interface EventSubscriber {
|
||||
* 通信通道接口
|
||||
*/
|
||||
export interface CommunicationChannel {
|
||||
/** 通道名称 */
|
||||
name: string
|
||||
/** 通道描述 */
|
||||
description: string
|
||||
restricted: boolean // 是否需要权限
|
||||
allowedApps: string[] // 允许访问的应用ID列表
|
||||
maxMessageSize: number // 最大消息大小(字节)
|
||||
messageRetention: number // 消息保留时间(毫秒)
|
||||
/** 是否需要权限 */
|
||||
restricted: boolean
|
||||
/** 允许的源应用ID列表 */
|
||||
/** 允许访问的应用ID列表 */
|
||||
allowedApps: string[]
|
||||
/** 最大消息大小(字节) */
|
||||
maxMessageSize: number
|
||||
/** 消息保留时间(毫秒) */
|
||||
messageRetention: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件统计信息
|
||||
*/
|
||||
export interface EventStatistics {
|
||||
/** 总发送消息数 */
|
||||
totalMessagesSent: number
|
||||
/** 总接收消息数 */
|
||||
totalMessagesReceived: number
|
||||
/** 总广播数 */
|
||||
totalBroadcasts: number
|
||||
/** 失败消息数 */
|
||||
failedMessages: number
|
||||
/** 激活的订阅者数 */
|
||||
activeSubscribers: number
|
||||
/** 通道使用情况 */
|
||||
channelUsage: Map<string, number>
|
||||
}
|
||||
|
||||
@@ -151,10 +198,12 @@ export class EventCommunicationService {
|
||||
totalBroadcasts: 0,
|
||||
failedMessages: 0,
|
||||
activeSubscribers: 0,
|
||||
channelUsage: new Map(),
|
||||
channelUsage: new Map()
|
||||
})
|
||||
|
||||
private processingInterval: number | null = null
|
||||
private lastProcessTime: number = 0
|
||||
private processInterval: number = 100 // 处理间隔(毫秒)
|
||||
private eventBus: IEventBuilder<EventCommunicationEvents>
|
||||
|
||||
constructor(eventBus: IEventBuilder<EventCommunicationEvents>) {
|
||||
@@ -173,7 +222,7 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
filter?: (message: EventMessage) => boolean
|
||||
priority?: MessagePriority
|
||||
} = {},
|
||||
} = {}
|
||||
): string {
|
||||
// 检查通道权限
|
||||
if (!this.canAccessChannel(appId, channel)) {
|
||||
@@ -189,7 +238,7 @@ export class EventCommunicationService {
|
||||
filter: options.filter,
|
||||
priority: options.priority || MessagePriority.NORMAL,
|
||||
createdAt: new Date(),
|
||||
active: true,
|
||||
active: true
|
||||
}
|
||||
|
||||
this.subscribers.set(subscriberId, subscriber)
|
||||
@@ -224,8 +273,11 @@ export class EventCommunicationService {
|
||||
type?: MessageType
|
||||
expiresIn?: number // 过期时间(毫秒)
|
||||
maxRetries?: number
|
||||
} = {},
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
if (this.getChannelSubscriberCount(channel) === 0) {
|
||||
throw new Error(`频道 ${channel} 无订阅者`)
|
||||
}
|
||||
// 检查发送者权限
|
||||
if (!this.canAccessChannel(senderId, channel)) {
|
||||
throw new Error(`应用 ${senderId} 无权向频道 ${channel} 发送消息`)
|
||||
@@ -253,7 +305,7 @@ export class EventCommunicationService {
|
||||
expiresAt: options.expiresIn ? new Date(now.getTime() + options.expiresIn) : undefined,
|
||||
status: MessageStatus.PENDING,
|
||||
retryCount: 0,
|
||||
maxRetries: options.maxRetries || 3,
|
||||
maxRetries: options.maxRetries || 3
|
||||
}
|
||||
|
||||
// 如果是点对点消息,直接发送
|
||||
@@ -277,7 +329,7 @@ export class EventCommunicationService {
|
||||
this.recordMessage(message)
|
||||
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`,
|
||||
`[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`
|
||||
)
|
||||
return messageId
|
||||
}
|
||||
@@ -292,11 +344,11 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {},
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
type: MessageType.BROADCAST,
|
||||
type: MessageType.BROADCAST
|
||||
})
|
||||
}
|
||||
|
||||
@@ -310,14 +362,14 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {},
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
const channel = 'cross-app'
|
||||
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
receiverId,
|
||||
type: MessageType.CROSS_APP,
|
||||
type: MessageType.CROSS_APP
|
||||
})
|
||||
}
|
||||
|
||||
@@ -330,7 +382,7 @@ export class EventCommunicationService {
|
||||
channel?: string
|
||||
limit?: number
|
||||
since?: Date
|
||||
} = {},
|
||||
} = {}
|
||||
): EventMessage[] {
|
||||
const history = this.messageHistory.get(appId) || []
|
||||
|
||||
@@ -363,7 +415,7 @@ export class EventCommunicationService {
|
||||
*/
|
||||
getChannelSubscriberCount(channel: string): number {
|
||||
return Array.from(this.subscribers.values()).filter(
|
||||
(sub) => sub.channel === channel && sub.active,
|
||||
(sub) => sub.channel === channel && sub.active
|
||||
).length
|
||||
}
|
||||
|
||||
@@ -377,7 +429,7 @@ export class EventCommunicationService {
|
||||
|
||||
this.channels.set(channel, {
|
||||
name: channel,
|
||||
...config,
|
||||
...config
|
||||
})
|
||||
|
||||
console.log(`创建通信频道: ${channel}`)
|
||||
@@ -442,7 +494,7 @@ export class EventCommunicationService {
|
||||
*/
|
||||
destroy(): void {
|
||||
if (this.processingInterval) {
|
||||
clearInterval(this.processingInterval)
|
||||
cancelAnimationFrame(this.processingInterval)
|
||||
this.processingInterval = null
|
||||
}
|
||||
|
||||
@@ -466,7 +518,7 @@ export class EventCommunicationService {
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 10, // 10KB
|
||||
messageRetention: 24 * 60 * 60 * 1000, // 24小时
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
})
|
||||
|
||||
// 应用间通信频道
|
||||
@@ -475,7 +527,7 @@ export class EventCommunicationService {
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 100, // 100KB
|
||||
messageRetention: 7 * 24 * 60 * 60 * 1000, // 7天
|
||||
messageRetention: 7 * 24 * 60 * 60 * 1000 // 7天
|
||||
})
|
||||
|
||||
// 用户交互频道
|
||||
@@ -484,7 +536,7 @@ export class EventCommunicationService {
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 5, // 5KB
|
||||
messageRetention: 60 * 60 * 1000, // 1小时
|
||||
messageRetention: 60 * 60 * 1000 // 1小时
|
||||
})
|
||||
|
||||
// 广播频道
|
||||
@@ -493,7 +545,7 @@ export class EventCommunicationService {
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 50, // 50KB
|
||||
messageRetention: 24 * 60 * 60 * 1000, // 24小时
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
})
|
||||
}
|
||||
|
||||
@@ -553,7 +605,7 @@ export class EventCommunicationService {
|
||||
// 只对非系统频道显示警告信息
|
||||
if (message.channel !== 'system') {
|
||||
console.warn(
|
||||
`[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`,
|
||||
`[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`
|
||||
)
|
||||
}
|
||||
return
|
||||
@@ -570,7 +622,7 @@ export class EventCommunicationService {
|
||||
await subscriber.handler(message)
|
||||
this.statistics.totalMessagesReceived++
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`,
|
||||
`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`向订阅者 ${subscriber.id} 发送消息失败:`, error)
|
||||
@@ -615,10 +667,20 @@ export class EventCommunicationService {
|
||||
* 开始消息处理循环
|
||||
*/
|
||||
private startMessageProcessing(): void {
|
||||
this.processingInterval = setInterval(() => {
|
||||
const processFrame = (timestamp: number) => {
|
||||
// 如果距离上次处理时间超过设定间隔,则处理消息
|
||||
if (timestamp - this.lastProcessTime >= this.processInterval) {
|
||||
this.processMessageQueue()
|
||||
this.cleanupExpiredMessages()
|
||||
}, 100) // 每100ms处理一次
|
||||
this.lastProcessTime = timestamp
|
||||
}
|
||||
|
||||
// 继续下一帧
|
||||
this.processingInterval = requestAnimationFrame(processFrame)
|
||||
}
|
||||
|
||||
// 启动处理循环
|
||||
this.processingInterval = requestAnimationFrame(processFrame)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,7 +742,7 @@ export class EventCommunicationService {
|
||||
*/
|
||||
private updateActiveSubscribersCount(): void {
|
||||
this.statistics.activeSubscribers = Array.from(this.subscribers.values()).filter(
|
||||
(sub) => sub.active,
|
||||
(sub) => sub.active
|
||||
).length
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
||||
import type { IEventBuilder } from '@/events/IEventBuilder'
|
||||
import type {
|
||||
EventCommunicationEvents,
|
||||
WindowFormDataUpdateParams,
|
||||
WindowFormDataUpdateParams
|
||||
} from './EventCommunicationService'
|
||||
import type { ResourceType } from './ResourceService'
|
||||
|
||||
@@ -19,36 +19,26 @@ import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||
* 系统服务配置接口
|
||||
*/
|
||||
export interface SystemServiceConfig {
|
||||
debug?: boolean
|
||||
maxMemoryUsage?: number
|
||||
maxCpuUsage?: number
|
||||
enablePerformanceMonitoring?: boolean
|
||||
enableSecurityAudit?: boolean
|
||||
autoCleanup?: boolean
|
||||
cleanupInterval?: number
|
||||
debug?: boolean // 是否开启调试模式
|
||||
autoCleanup?: boolean // 是否自动清理
|
||||
cleanupInterval?: number // 自动清理间隔
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统状态接口
|
||||
*/
|
||||
export interface SystemStatus {
|
||||
initialized: boolean
|
||||
running: boolean
|
||||
initialized: boolean // 系统是否初始化完成
|
||||
running: boolean // 系统是否运行中
|
||||
servicesStatus: {
|
||||
windowService: boolean
|
||||
resourceService: boolean
|
||||
eventService: boolean
|
||||
sandboxEngine: boolean
|
||||
lifecycleManager: boolean
|
||||
windowService: boolean // 窗体服务是否启动
|
||||
resourceService: boolean // 资源服务是否启动
|
||||
eventService: boolean // 事件服务是否启动
|
||||
sandboxEngine: boolean // 沙箱引擎是否启动
|
||||
lifecycleManager: boolean // 生命周期管理器是否启动
|
||||
}
|
||||
performance: {
|
||||
memoryUsage: number
|
||||
cpuUsage: number
|
||||
activeApps: number
|
||||
activeWindows: number
|
||||
}
|
||||
uptime: number
|
||||
lastError?: string
|
||||
uptime: number // 系统运行时间
|
||||
lastError?: string // 最后一次错误
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,15 +78,9 @@ export class SystemServiceIntegration {
|
||||
resourceService: false,
|
||||
eventService: false,
|
||||
sandboxEngine: false,
|
||||
lifecycleManager: false,
|
||||
lifecycleManager: false
|
||||
},
|
||||
performance: {
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
activeApps: 0,
|
||||
activeWindows: 0,
|
||||
},
|
||||
uptime: 0,
|
||||
uptime: 0
|
||||
})
|
||||
|
||||
// 性能监控
|
||||
@@ -106,13 +90,9 @@ export class SystemServiceIntegration {
|
||||
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,
|
||||
...config
|
||||
}
|
||||
|
||||
this.startTime = new Date()
|
||||
@@ -141,11 +121,6 @@ export class SystemServiceIntegration {
|
||||
// 设置SDK消息处理
|
||||
this.setupSDKMessageHandling()
|
||||
|
||||
// 启动性能监控
|
||||
if (this.config.enablePerformanceMonitoring) {
|
||||
this.startPerformanceMonitoring()
|
||||
}
|
||||
|
||||
// 启动自动清理
|
||||
if (this.config.autoCleanup) {
|
||||
this.startAutoCleanup()
|
||||
@@ -167,7 +142,7 @@ export class SystemServiceIntegration {
|
||||
// 发送系统就绪事件
|
||||
this.eventService.sendMessage('system', 'system-ready', {
|
||||
timestamp: new Date(),
|
||||
services: Object.keys(this.systemStatus.servicesStatus),
|
||||
services: Object.keys(this.systemStatus.servicesStatus)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('系统服务初始化失败:', error)
|
||||
@@ -180,7 +155,6 @@ export class SystemServiceIntegration {
|
||||
* 获取系统状态
|
||||
*/
|
||||
getSystemStatus(): SystemStatus {
|
||||
this.updateSystemStatus()
|
||||
return { ...this.systemStatus }
|
||||
}
|
||||
|
||||
@@ -240,7 +214,7 @@ export class SystemServiceIntegration {
|
||||
return {
|
||||
success: true,
|
||||
data: result,
|
||||
requestId,
|
||||
requestId
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('SDK调用失败:', error)
|
||||
@@ -248,7 +222,7 @@ export class SystemServiceIntegration {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
requestId,
|
||||
requestId
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,8 +298,6 @@ export class SystemServiceIntegration {
|
||||
console.log('系统服务已关闭')
|
||||
}
|
||||
|
||||
// 私有方法
|
||||
|
||||
/**
|
||||
* 初始化所有服务
|
||||
*/
|
||||
@@ -356,7 +328,7 @@ export class SystemServiceIntegration {
|
||||
this.windowService,
|
||||
this.resourceService,
|
||||
this.eventService,
|
||||
this.sandboxEngine,
|
||||
this.sandboxEngine
|
||||
)
|
||||
this.systemStatus.servicesStatus.lifecycleManager = true
|
||||
}
|
||||
@@ -380,15 +352,15 @@ export class SystemServiceIntegration {
|
||||
'onWindowStateChanged',
|
||||
(windowId: string, newState: string, oldState: string) => {
|
||||
console.log(
|
||||
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`,
|
||||
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`
|
||||
)
|
||||
this.eventService.sendMessage('system', 'window-state-change', {
|
||||
windowId,
|
||||
newState,
|
||||
oldState,
|
||||
oldState
|
||||
})
|
||||
console.log(`[SystemIntegration] 已发送 window-state-change 消息到事件通信服务`)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// 监听窗体关闭事件,自动停止对应的应用
|
||||
@@ -412,24 +384,13 @@ export class SystemServiceIntegration {
|
||||
// 监听窗体数据更新事件
|
||||
this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
|
||||
// 只有在有订阅者时才发送消息
|
||||
if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) {
|
||||
this.eventService.sendMessage('system', 'window-form-data-update', data)
|
||||
console.log(`[SystemIntegration] 已发送 window-form-data-update 消息到事件通信服务`)
|
||||
} else {
|
||||
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-data-update 消息`)
|
||||
}
|
||||
})
|
||||
|
||||
// 监听窗体调整尺寸开始事件
|
||||
this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`)
|
||||
// 只有在有订阅者时才发送消息
|
||||
if (this.eventService.getChannelSubscriberCount('window-form-resize-start') > 0) {
|
||||
this.eventService.sendMessage('system', 'window-form-resize-start', { windowId })
|
||||
} else {
|
||||
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-resize-start 消息`)
|
||||
}
|
||||
})
|
||||
|
||||
// 监听窗体调整尺寸过程中事件
|
||||
@@ -438,43 +399,21 @@ export class SystemServiceIntegration {
|
||||
(windowId: string, width: number, height: number) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸过程中事件: ${windowId}`, {
|
||||
width,
|
||||
height,
|
||||
height
|
||||
})
|
||||
// 只有在有订阅者时才发送消息
|
||||
if (this.eventService.getChannelSubscriberCount('window-form-resizing') > 0) {
|
||||
this.eventService.sendMessage('system', 'window-form-resizing', {
|
||||
windowId,
|
||||
width,
|
||||
height,
|
||||
height
|
||||
})
|
||||
} else {
|
||||
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-resizing 消息`)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听窗体调整尺寸结束事件
|
||||
this.eventBus.addEventListener('onWindowFormResizeEnd', (windowId: string) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`)
|
||||
// 只有在有订阅者时才发送消息
|
||||
if (this.eventService.getChannelSubscriberCount('window-form-resize-end') > 0) {
|
||||
this.eventService.sendMessage('system', 'window-form-resize-end', { windowId })
|
||||
} else {
|
||||
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-resize-end 消息`)
|
||||
}
|
||||
})
|
||||
|
||||
// 监听资源配额超出
|
||||
this.eventBus.addEventListener(
|
||||
'onResourceQuotaExceeded',
|
||||
(appId: string, resourceType: ResourceType) => {
|
||||
console.log(`[SystemIntegration] 接收到资源配额超出事件: ${appId} - ${resourceType}`)
|
||||
this.eventService.sendMessage('system', 'resource-quota-exceeded', {
|
||||
appId,
|
||||
resourceType,
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,9 +442,9 @@ export class SystemServiceIntegration {
|
||||
iframe.contentWindow?.postMessage(
|
||||
{
|
||||
type: 'system:response',
|
||||
...result,
|
||||
...result
|
||||
},
|
||||
'*',
|
||||
'*'
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -567,9 +506,9 @@ export class SystemServiceIntegration {
|
||||
type: 'system:storage-response',
|
||||
requestId,
|
||||
result,
|
||||
success,
|
||||
success
|
||||
},
|
||||
'*',
|
||||
'*'
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -660,7 +599,7 @@ export class SystemServiceIntegration {
|
||||
const windowData = this.windowService.getWindow(windowId)
|
||||
return {
|
||||
width: windowData?.config.width,
|
||||
height: windowData?.config.height,
|
||||
height: windowData?.config.height
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -714,7 +653,7 @@ export class SystemServiceIntegration {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: {} as Record<string, string>, // 简化headers处理
|
||||
url: response.url,
|
||||
url: response.url
|
||||
}
|
||||
: null
|
||||
|
||||
@@ -726,7 +665,7 @@ export class SystemServiceIntegration {
|
||||
return {
|
||||
requestCount: requests.length,
|
||||
failureCount: requests.filter((r) => r.status && r.status >= 400).length,
|
||||
averageTime: 0, // 需要实现时间统计
|
||||
averageTime: 0 // 需要实现时间统计
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -750,7 +689,7 @@ export class SystemServiceIntegration {
|
||||
this.sandboxEngine.sendMessage(app.sandboxId, {
|
||||
type: 'system:event',
|
||||
subscriptionId: data.subscriptionId,
|
||||
message,
|
||||
message
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -800,10 +739,10 @@ export class SystemServiceIntegration {
|
||||
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
screenResolution: {
|
||||
width: screen.width,
|
||||
height: screen.height,
|
||||
height: screen.height
|
||||
},
|
||||
colorDepth: screen.colorDepth,
|
||||
pixelRatio: window.devicePixelRatio,
|
||||
pixelRatio: window.devicePixelRatio
|
||||
}
|
||||
|
||||
case 'getAppInfo':
|
||||
@@ -815,7 +754,7 @@ export class SystemServiceIntegration {
|
||||
version: app.version,
|
||||
permissions: app.manifest.permissions,
|
||||
createdAt: app.installedAt,
|
||||
lastActiveAt: app.lastActiveAt,
|
||||
lastActiveAt: app.lastActiveAt
|
||||
}
|
||||
: null
|
||||
|
||||
@@ -851,32 +790,6 @@ export class SystemServiceIntegration {
|
||||
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秒检查一次
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始自动清理
|
||||
*/
|
||||
@@ -894,20 +807,6 @@ export class SystemServiceIntegration {
|
||||
}, 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使用率
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已初始化
|
||||
*/
|
||||
@@ -927,7 +826,7 @@ export class SystemServiceIntegration {
|
||||
})
|
||||
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
console.error('未处理的Promise拒绝:', event.reason)
|
||||
// console.error('未处理的Promise拒绝:', event.reason)
|
||||
this.systemStatus.lastError = event.reason?.message || '未处理的Promise拒绝'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,18 +13,6 @@
|
||||
{{ systemStatus.running ? '正常' : '错误' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span>活跃应用:</span>
|
||||
<span>{{ systemStatus.performance.activeApps }}</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span>活跃窗体:</span>
|
||||
<span>{{ systemStatus.performance.activeWindows }}</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span>内存使用:</span>
|
||||
<span>{{ Math.round(systemStatus.performance.memoryUsage) }}MB</span>
|
||||
</div>
|
||||
<button @click="showSystemStatus = false" class="close-btn">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,12 +56,6 @@ const systemStatus = ref<SystemStatus>({
|
||||
sandboxEngine: false,
|
||||
lifecycleManager: false
|
||||
},
|
||||
performance: {
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
activeApps: 0,
|
||||
activeWindows: 0
|
||||
},
|
||||
uptime: 0
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user