This commit is contained in:
2025-10-10 10:08:05 +08:00
parent ed0527bf27
commit 204dd4781b
6 changed files with 235 additions and 816 deletions

View File

@@ -14,9 +14,7 @@ registerBuiltInApps()
// 初始化系统服务 // 初始化系统服务
const systemService = new SystemServiceIntegration({ const systemService = new SystemServiceIntegration({
debug: import.meta.env.DEV, debug: import.meta.env.DEV
enablePerformanceMonitoring: true,
enableSecurityAudit: true
}) })
// 创建应用实例 // 创建应用实例

View File

@@ -20,7 +20,7 @@ export enum AppLifecycleState {
UNINSTALLING = 'uninstalling', UNINSTALLING = 'uninstalling',
ERROR = 'error', ERROR = 'error',
CRASHED = 'crashed', CRASHED = 'crashed',
AVAILABLE = 'available', // 外置应用可用但未注册状态 AVAILABLE = 'available' // 外置应用可用但未注册状态
} }
/** /**
@@ -81,16 +81,6 @@ export interface AppInstance {
persistent: boolean 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, windowService: WindowService,
resourceService: ResourceService, resourceService: ResourceService,
eventService: EventCommunicationService, eventService: EventCommunicationService,
sandboxEngine: ApplicationSandboxEngine, sandboxEngine: ApplicationSandboxEngine
) { ) {
this.windowService = windowService this.windowService = windowService
this.resourceService = resourceService this.resourceService = resourceService
@@ -146,122 +136,6 @@ export class ApplicationLifecycleManager {
this.sandboxEngine = sandboxEngine this.sandboxEngine = sandboxEngine
this.setupEventListeners() 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> { async startApp(appId: string, options: AppStartOptions = {}): Promise<string> {
let app = this.installedApps.get(appId) let app = this.installedApps.get(appId)
console.log('-----------------------------')
// 如果应用未安装,检查是否为外置应用 // 如果应用未安装,检查是否为外置应用
let isExternalApp = false let isExternalApp = false
if (!app) { if (!app) {
@@ -277,7 +153,7 @@ export class ApplicationLifecycleManager {
if (externalApp) { if (externalApp) {
console.log(`[LifecycleManager] 发现外置应用 ${appId}`) console.log(`[LifecycleManager] 发现外置应用 ${appId}`)
isExternalApp = true isExternalApp = true
// 为外部应用创建临时实例 // 为外部应用创建临时实例
const now = new Date() const now = new Date()
app = { app = {
@@ -292,7 +168,7 @@ export class ApplicationLifecycleManager {
cpuUsage: 0, cpuUsage: 0,
version: externalApp.manifest.version, version: externalApp.manifest.version,
autoStart: false, autoStart: false,
persistent: false, persistent: false
} }
} }
} }
@@ -312,21 +188,7 @@ export class ApplicationLifecycleManager {
this.updateAppState(app, AppLifecycleState.STARTING) this.updateAppState(app, AppLifecycleState.STARTING)
// 检查是否为内置应用 // 检查是否为内置应用
let isBuiltInApp = false let isBuiltInApp = true
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 windowId: string | undefined let windowId: string | undefined
@@ -341,23 +203,12 @@ export class ApplicationLifecycleManager {
minWidth: app.manifest.window?.minWidth, minWidth: app.manifest.window?.minWidth,
minHeight: app.manifest.window?.minHeight, minHeight: app.manifest.window?.minHeight,
maxWidth: app.manifest.window?.maxWidth, maxWidth: app.manifest.window?.maxWidth,
maxHeight: app.manifest.window?.maxHeight, maxHeight: app.manifest.window?.maxHeight
} }
const windowInstance = await this.windowService.createWindow(appId, windowConfig) const windowInstance = await this.windowService.createWindow(appId, windowConfig)
windowId = windowInstance.id windowId = windowInstance.id
app.windowId = windowId 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秒 networkTimeout: 15000, // 增加超时时间到15秒
csp: csp:
app.manifest.contentSecurity?.policy || 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( const sandbox = await this.sandboxEngine.createSandbox(
appId, appId,
windowId || 'background', windowId || 'background',
sandboxConfig, sandboxConfig
) )
app.sandboxId = sandbox.id app.sandboxId = sandbox.id
@@ -417,7 +268,7 @@ export class ApplicationLifecycleManager {
async stopApp(appId: string): Promise<boolean> { async stopApp(appId: string): Promise<boolean> {
// 首先从已安装应用中查找 // 首先从已安装应用中查找
let app = this.installedApps.get(appId) let app = this.installedApps.get(appId)
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例) // 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
if (!app) { if (!app) {
for (const runningApp of this.runningProcesses.values()) { for (const runningApp of this.runningProcesses.values()) {
@@ -427,7 +278,7 @@ export class ApplicationLifecycleManager {
} }
} }
} }
if (!app) { if (!app) {
throw new Error(`应用 ${appId} 未安装或未运行`) throw new Error(`应用 ${appId} 未安装或未运行`)
} }
@@ -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)
}
/** /**
* 获取应用信息 * 获取应用信息
*/ */
@@ -600,7 +352,7 @@ export class ApplicationLifecycleManager {
isAppRunning(appId: string): boolean { isAppRunning(appId: string): boolean {
// 首先从已安装应用中查找 // 首先从已安装应用中查找
let app = this.installedApps.get(appId) let app = this.installedApps.get(appId)
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例) // 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
if (!app) { if (!app) {
for (const runningApp of this.runningProcesses.values()) { for (const runningApp of this.runningProcesses.values()) {
@@ -610,7 +362,7 @@ export class ApplicationLifecycleManager {
} }
} }
} }
return app?.state === AppLifecycleState.RUNNING || app?.state === AppLifecycleState.SUSPENDED return app?.state === AppLifecycleState.RUNNING || app?.state === AppLifecycleState.SUSPENDED
} }
@@ -629,7 +381,7 @@ export class ApplicationLifecycleManager {
cpuUsage: app.cpuUsage, cpuUsage: app.cpuUsage,
startedAt: app.startedAt, startedAt: app.startedAt,
lastActiveAt: app.lastActiveAt, 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(`[LifecycleManager] 为内置应用 ${appId} 创建 AppRenderer 组件`)
console.log('----------------------------------')
const app = createApp({ const app = createApp({
components: { AppRenderer }, 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, getResourceService: () => this.resourceService,
getEventService: () => this.eventService, getEventService: () => this.eventService,
getSandboxEngine: () => this.sandboxEngine, 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, version: externalApp.manifest.version,
autoStart: false, autoStart: false,
persistent: false, persistent: false,
isExternal: true, isExternal: true
} }
apps.push(appInstance) 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', { this.eventService.sendMessage('system', 'app-lifecycle', {
type: 'error', type: 'error',
appId, appId,
error: error.message, error: error.message
}) })
console.error(`应用 ${appId} 发生错误:`, error) console.error(`应用 ${appId} 发生错误:`, error)
@@ -1050,7 +581,7 @@ export class ApplicationLifecycleManager {
type: 'stateChanged', type: 'stateChanged',
appId: app.id, appId: app.id,
newState, newState,
oldState, oldState
}) })
} }
} }

View File

@@ -109,10 +109,7 @@ export class ApplicationSandboxEngine {
private resourceService: ResourceService private resourceService: ResourceService
private eventService: EventCommunicationService private eventService: EventCommunicationService
constructor( constructor(resourceService: ResourceService, eventService: EventCommunicationService) {
resourceService: ResourceService,
eventService: EventCommunicationService
) {
this.resourceService = resourceService this.resourceService = resourceService
this.eventService = eventService this.eventService = eventService
this.startPerformanceMonitoring() this.startPerformanceMonitoring()
@@ -127,7 +124,7 @@ export class ApplicationSandboxEngine {
config: Partial<SandboxConfig> = {} config: Partial<SandboxConfig> = {}
): Promise<SandboxInstance> { ): Promise<SandboxInstance> {
const sandboxId = uuidv4() const sandboxId = uuidv4()
const defaultConfig: SandboxConfig = { const defaultConfig: SandboxConfig = {
type: SandboxType.IFRAME, type: SandboxType.IFRAME,
securityLevel: SecurityLevel.HIGH, securityLevel: SecurityLevel.HIGH,
@@ -166,21 +163,20 @@ export class ApplicationSandboxEngine {
try { try {
// 根据类型创建沙箱容器 // 根据类型创建沙箱容器
await this.createSandboxContainer(sandbox) await this.createSandboxContainer(sandbox)
// 设置安全策略 // 设置安全策略
this.applySecurity(sandbox) this.applySecurity(sandbox)
// 设置性能监控 // 设置性能监控
this.setupPerformanceMonitoring(sandbox) this.setupPerformanceMonitoring(sandbox)
// 更新状态 // 更新状态
this.updateSandboxState(sandbox, SandboxState.READY) this.updateSandboxState(sandbox, SandboxState.READY)
this.sandboxes.set(sandboxId, sandbox) this.sandboxes.set(sandboxId, sandbox)
console.log(`沙箱 ${sandboxId} 创建成功`) console.log(`沙箱 ${sandboxId} 创建成功`)
return sandbox return sandbox
} catch (error) { } catch (error) {
this.updateSandboxState(sandbox, SandboxState.ERROR) this.updateSandboxState(sandbox, SandboxState.ERROR)
sandbox.errors.push(error instanceof Error ? error.message : String(error)) sandbox.errors.push(error instanceof Error ? error.message : String(error))
@@ -200,23 +196,25 @@ export class ApplicationSandboxEngine {
try { try {
console.log(`开始加载应用: ${sandbox.appId}, 沙箱ID: ${sandboxId}`) console.log(`开始加载应用: ${sandbox.appId}, 沙箱ID: ${sandboxId}`)
this.updateSandboxState(sandbox, SandboxState.RUNNING) this.updateSandboxState(sandbox, SandboxState.RUNNING)
if (sandbox.config.type === SandboxType.IFRAME && sandbox.iframe) { if (sandbox.config.type === SandboxType.IFRAME && sandbox.iframe) {
console.log(`使用iframe加载应用: ${applicationUrl}`) console.log(`使用iframe加载应用: ${applicationUrl}`)
// 检查iframe是否已挂载到DOM // 检查iframe是否已挂载到DOM
if (!document.contains(sandbox.iframe)) { if (!document.contains(sandbox.iframe)) {
console.warn('检测到iframe未挂载到DOM尝试重新挂载') console.warn('检测到iframe未挂载到DOM尝试重新挂载')
await this.mountIframeToWindow(sandbox) await this.mountIframeToWindow(sandbox)
} }
// 设置iframe源 // 设置iframe源
sandbox.iframe.src = applicationUrl sandbox.iframe.src = applicationUrl
// 等待加载完成 // 等待加载完成
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => { 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('应用加载超时')) reject(new Error('应用加载超时'))
}, sandbox.config.networkTimeout) }, sandbox.config.networkTimeout)
@@ -241,7 +239,7 @@ export class ApplicationSandboxEngine {
}) })
return true return true
} }
return false return false
} catch (error) { } catch (error) {
console.error(`加载应用失败: ${sandbox.appId}`, error) console.error(`加载应用失败: ${sandbox.appId}`, error)
@@ -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
}
}
/** /**
* 销毁沙箱 * 销毁沙箱
*/ */
@@ -320,18 +260,18 @@ export class ApplicationSandboxEngine {
try { try {
this.updateSandboxState(sandbox, SandboxState.DESTROYED) this.updateSandboxState(sandbox, SandboxState.DESTROYED)
// 移除消息事件监听器 // 移除消息事件监听器
if (sandbox.messageHandler) { if (sandbox.messageHandler) {
window.removeEventListener('message', sandbox.messageHandler); window.removeEventListener('message', sandbox.messageHandler)
sandbox.messageHandler = undefined; sandbox.messageHandler = undefined
} }
// 清理DOM元素 // 清理DOM元素
if (sandbox.iframe) { if (sandbox.iframe) {
sandbox.iframe.remove() sandbox.iframe.remove()
} }
if (sandbox.container) { if (sandbox.container) {
sandbox.container.remove() sandbox.container.remove()
} }
@@ -343,10 +283,10 @@ export class ApplicationSandboxEngine {
// 清理性能数据 // 清理性能数据
this.performanceData.delete(sandboxId) this.performanceData.delete(sandboxId)
// 从集合中移除 // 从集合中移除
this.sandboxes.delete(sandboxId) this.sandboxes.delete(sandboxId)
console.log(`沙箱 ${sandboxId} 已销毁`) console.log(`沙箱 ${sandboxId} 已销毁`)
return true return true
} catch (error) { } catch (error) {
@@ -366,7 +306,7 @@ export class ApplicationSandboxEngine {
* 获取应用的所有沙箱 * 获取应用的所有沙箱
*/ */
getAppSandboxes(appId: string): SandboxInstance[] { 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)
} }
/** /**
@@ -396,7 +336,7 @@ export class ApplicationSandboxEngine {
sandbox.worker.postMessage(message) sandbox.worker.postMessage(message)
return true return true
} }
return false return false
} catch (error) { } catch (error) {
console.error('发送消息到沙箱失败:', error) console.error('发送消息到沙箱失败:', error)
@@ -421,7 +361,7 @@ export class ApplicationSandboxEngine {
clearInterval(this.monitoringInterval) clearInterval(this.monitoringInterval)
this.monitoringInterval = null this.monitoringInterval = null
} }
this.cleanup() this.cleanup()
console.log('沙箱引擎已销毁') console.log('沙箱引擎已销毁')
} }
@@ -453,10 +393,10 @@ export class ApplicationSandboxEngine {
private async createIframeSandbox(sandbox: SandboxInstance): Promise<void> { private async createIframeSandbox(sandbox: SandboxInstance): Promise<void> {
const iframe = document.createElement('iframe') const iframe = document.createElement('iframe')
iframe.id = `sandbox-${sandbox.id}` iframe.id = `sandbox-${sandbox.id}`
// 设置sandbox属性 // 设置sandbox属性
const sandboxAttributes: string[] = [] const sandboxAttributes: string[] = []
if (sandbox.config.allowScripts) sandboxAttributes.push('allow-scripts') if (sandbox.config.allowScripts) sandboxAttributes.push('allow-scripts')
if (sandbox.config.allowSameOrigin) sandboxAttributes.push('allow-same-origin') if (sandbox.config.allowSameOrigin) sandboxAttributes.push('allow-same-origin')
if (sandbox.config.allowForms) sandboxAttributes.push('allow-forms') if (sandbox.config.allowForms) sandboxAttributes.push('allow-forms')
@@ -465,9 +405,9 @@ export class ApplicationSandboxEngine {
if (sandbox.config.allowPointerLock) sandboxAttributes.push('allow-pointer-lock') if (sandbox.config.allowPointerLock) sandboxAttributes.push('allow-pointer-lock')
if (sandbox.config.allowPresentation) sandboxAttributes.push('allow-presentation') if (sandbox.config.allowPresentation) sandboxAttributes.push('allow-presentation')
if (sandbox.config.allowTopNavigation) sandboxAttributes.push('allow-top-navigation') if (sandbox.config.allowTopNavigation) sandboxAttributes.push('allow-top-navigation')
iframe.sandbox = sandboxAttributes.join(' ') iframe.sandbox = sandboxAttributes.join(' ')
// 设置样式 // 设置样式
iframe.style.cssText = ` iframe.style.cssText = `
width: 100%; width: 100%;
@@ -483,11 +423,11 @@ export class ApplicationSandboxEngine {
sandbox.iframe = iframe sandbox.iframe = iframe
sandbox.container = iframe sandbox.container = iframe
// 将iframe挂载到对应的窗口内容区域 // 将iframe挂载到对应的窗口内容区域
await this.mountIframeToWindow(sandbox) await this.mountIframeToWindow(sandbox)
} }
/** /**
* 将iframe挂载到窗口内容区域 * 将iframe挂载到窗口内容区域
*/ */
@@ -512,18 +452,18 @@ export class ApplicationSandboxEngine {
} }
throw new Error(`找不到窗口元素: window-${sandbox.windowId}`) throw new Error(`找不到窗口元素: window-${sandbox.windowId}`)
} }
const contentArea = windowElement.querySelector('.window-content') const contentArea = windowElement.querySelector('.window-content')
if (!contentArea) { if (!contentArea) {
throw new Error(`找不到窗口内容区域: window-${sandbox.windowId}`) throw new Error(`找不到窗口内容区域: window-${sandbox.windowId}`)
} }
// 替换窗口中的默认iframe // 替换窗口中的默认iframe
const existingIframe = contentArea.querySelector('iframe') const existingIframe = contentArea.querySelector('iframe')
if (existingIframe) { if (existingIframe) {
contentArea.removeChild(existingIframe) contentArea.removeChild(existingIframe)
} }
contentArea.appendChild(sandbox.iframe!) contentArea.appendChild(sandbox.iframe!)
} }
@@ -567,9 +507,9 @@ export class ApplicationSandboxEngine {
const blob = new Blob([workerScript], { type: 'application/javascript' }) const blob = new Blob([workerScript], { type: 'application/javascript' })
const workerUrl = URL.createObjectURL(blob) const workerUrl = URL.createObjectURL(blob)
const worker = new Worker(workerUrl) const worker = new Worker(workerUrl)
worker.onmessage = (e) => { worker.onmessage = (e) => {
const { type, error } = e.data const { type, error } = e.data
if (type === 'error') { if (type === 'error') {
@@ -593,9 +533,9 @@ export class ApplicationSandboxEngine {
private async createShadowDOMSandbox(sandbox: SandboxInstance): Promise<void> { private async createShadowDOMSandbox(sandbox: SandboxInstance): Promise<void> {
const container = document.createElement('div') const container = document.createElement('div')
container.id = `sandbox-${sandbox.id}` container.id = `sandbox-${sandbox.id}`
const shadowRoot = container.attachShadow({ mode: 'closed' }) const shadowRoot = container.attachShadow({ mode: 'closed' })
// 添加样式隔离 // 添加样式隔离
const style = document.createElement('style') const style = document.createElement('style')
style.textContent = ` style.textContent = `
@@ -626,16 +566,16 @@ export class ApplicationSandboxEngine {
} }
// 这些头部主要用于服务器端设置,在客户端我们通过其他方式实现 // 这些头部主要用于服务器端设置,在客户端我们通过其他方式实现
// 监听iframe的消息事件 // 监听iframe的消息事件
const messageHandler = (event: MessageEvent) => { const messageHandler = (event: MessageEvent) => {
if (event.source === sandbox.iframe!.contentWindow) { if (event.source === sandbox.iframe!.contentWindow) {
this.handleSandboxMessage(sandbox, event.data) this.handleSandboxMessage(sandbox, event.data)
} }
}; }
window.addEventListener('message', messageHandler); window.addEventListener('message', messageHandler)
// 存储事件监听器引用,以便在销毁时移除 // 存储事件监听器引用,以便在销毁时移除
sandbox.messageHandler = messageHandler; sandbox.messageHandler = messageHandler
// 简化安全限制主要依赖iframe的sandbox属性 // 简化安全限制主要依赖iframe的sandbox属性
sandbox.iframe.addEventListener('load', () => { sandbox.iframe.addEventListener('load', () => {
@@ -675,15 +615,15 @@ export class ApplicationSandboxEngine {
case 'app:ready': case 'app:ready':
sandbox.lastActiveAt = new Date() sandbox.lastActiveAt = new Date()
break break
case 'app:error': case 'app:error':
sandbox.errors.push(message.error || '未知错误') sandbox.errors.push(message.error || '未知错误')
break break
case 'app:resource-request': case 'app:resource-request':
this.handleResourceRequest(sandbox, message.data) this.handleResourceRequest(sandbox, message.data)
break break
case 'app:performance': case 'app:performance':
this.recordPerformance(sandbox, message.data) this.recordPerformance(sandbox, message.data)
break break
@@ -695,10 +635,10 @@ export class ApplicationSandboxEngine {
*/ */
private async handleResourceRequest(sandbox: SandboxInstance, request: any): Promise<void> { private async handleResourceRequest(sandbox: SandboxInstance, request: any): Promise<void> {
const { type, data } = request const { type, data } = request
try { try {
let result = null let result = null
switch (type) { switch (type) {
case 'storage': case 'storage':
if (data.action === 'get') { if (data.action === 'get') {
@@ -707,12 +647,16 @@ export class ApplicationSandboxEngine {
result = await this.resourceService.setStorage(sandbox.appId, data.key, data.value) result = await this.resourceService.setStorage(sandbox.appId, data.key, data.value)
} }
break break
case 'network': 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 break
} }
// 发送结果回沙箱 // 发送结果回沙箱
this.sendMessage(sandbox.id, { this.sendMessage(sandbox.id, {
type: 'system:resource-response', type: 'system:resource-response',
@@ -1171,10 +1115,10 @@ export class ApplicationSandboxEngine {
// 通知系统应用已准备就绪 // 通知系统应用已准备就绪
window.parent.postMessage({ type: 'app:ready' }, '*'); window.parent.postMessage({ type: 'app:ready' }, '*');
})(); })();
`; `
iframeDoc.head.appendChild(script) iframeDoc.head.appendChild(script)
} }
/** /**
* 设置性能监控 * 设置性能监控
@@ -1260,9 +1204,12 @@ export class ApplicationSandboxEngine {
private collectPerformanceMetrics(sandbox: SandboxInstance): void { private collectPerformanceMetrics(sandbox: SandboxInstance): void {
if (sandbox.iframe && sandbox.iframe.contentWindow) { if (sandbox.iframe && sandbox.iframe.contentWindow) {
// 请求性能数据 // 请求性能数据
sandbox.iframe.contentWindow.postMessage({ sandbox.iframe.contentWindow.postMessage(
type: 'system:performance-request' {
}, '*') type: 'system:performance-request'
},
'*'
)
} }
} }
@@ -1272,7 +1219,7 @@ export class ApplicationSandboxEngine {
private updateSandboxState(sandbox: SandboxInstance, newState: SandboxState): void { private updateSandboxState(sandbox: SandboxInstance, newState: SandboxState): void {
const oldState = sandbox.state const oldState = sandbox.state
sandbox.state = newState sandbox.state = newState
// 触发状态变化事件 // 触发状态变化事件
this.eventService.sendMessage('system', 'sandbox-state-change', { this.eventService.sendMessage('system', 'sandbox-state-change', {
sandboxId: sandbox.id, sandboxId: sandbox.id,
@@ -1280,4 +1227,4 @@ export class ApplicationSandboxEngine {
oldState oldState
}) })
} }
} }

View File

@@ -8,49 +8,75 @@ import type { ResourceType } from './ResourceService'
* 消息类型枚举 * 消息类型枚举
*/ */
export enum MessageType { export enum MessageType {
/** 系统事件 */
SYSTEM = 'system', SYSTEM = 'system',
/** 应用事件 */
APPLICATION = 'application', APPLICATION = 'application',
/** 用户交互事件 */
USER_INTERACTION = 'user_interaction', USER_INTERACTION = 'user_interaction',
/** 跨应用事件 */
CROSS_APP = 'cross_app', CROSS_APP = 'cross_app',
BROADCAST = 'broadcast', /** 广播事件 */
BROADCAST = 'broadcast'
} }
/** /**
* 消息优先级枚举 * 消息优先级枚举
*/ */
export enum MessagePriority { export enum MessagePriority {
/** 低优先级 */
LOW = 0, LOW = 0,
/** 正常优先级 */
NORMAL = 1, NORMAL = 1,
/** 高优先级 */
HIGH = 2, HIGH = 2,
CRITICAL = 3, /** 紧急优先级 */
CRITICAL = 3
} }
/** /**
* 消息状态枚举 * 消息状态枚举
*/ */
export enum MessageStatus { export enum MessageStatus {
/** 等待发送 */
PENDING = 'pending', PENDING = 'pending',
/** 已发送 */
SENT = 'sent', SENT = 'sent',
/** 已送达 */
DELIVERED = 'delivered', DELIVERED = 'delivered',
/** 发送失败 */
FAILED = 'failed', FAILED = 'failed',
EXPIRED = 'expired', /** 已取消 */
EXPIRED = 'expired'
} }
/** /**
* 事件消息接口 * 事件消息接口
*/ */
export interface EventMessage { export interface EventMessage {
/** 消息ID */
id: string id: string
/** 消息类型 */
type: MessageType type: MessageType
/** 消息优先级 */
priority: MessagePriority priority: MessagePriority
/** 发送者ID */
senderId: string senderId: string
receiverId?: string // undefined表示广播消息 /** 接收者ID, undefined表示广播消息 */
receiverId?: string
/** 消息频道 */
channel: string channel: string
/** 消息内容 */
payload: any payload: any
/** 消息发送时间 */
timestamp: Date timestamp: Date
/** 消息过期时间 */
expiresAt?: Date expiresAt?: Date
/** 消息状态 */
status: MessageStatus status: MessageStatus
/** 重试次数 */
retryCount: number retryCount: number
/** 最大重试次数 */
maxRetries: number maxRetries: number
} }
@@ -58,13 +84,21 @@ export interface EventMessage {
* 事件订阅者接口 * 事件订阅者接口
*/ */
export interface EventSubscriber { export interface EventSubscriber {
/** 订阅者ID */
id: string id: string
/** 应用ID */
appId: string appId: string
/** 消息频道 */
channel: string channel: string
/** 订阅者处理函数 */
handler: (message: EventMessage) => void | Promise<void> handler: (message: EventMessage) => void | Promise<void>
/** 消息过滤器 */
filter?: (message: EventMessage) => boolean filter?: (message: EventMessage) => boolean
/** 订阅者优先级 */
priority: MessagePriority priority: MessagePriority
/** 创建时间 */
createdAt: Date createdAt: Date
/** 是否启用 */
active: boolean active: boolean
} }
@@ -72,23 +106,36 @@ export interface EventSubscriber {
* 通信通道接口 * 通信通道接口
*/ */
export interface CommunicationChannel { export interface CommunicationChannel {
/** 通道名称 */
name: string name: string
/** 通道描述 */
description: string description: string
restricted: boolean // 是否需要权限 /** 是否需要权限 */
allowedApps: string[] // 允许访问的应用ID列表 restricted: boolean
maxMessageSize: number // 最大消息大小(字节) /** 允许的源应用ID列表 */
messageRetention: number // 消息保留时间(毫秒) /** 允许访问的应用ID列表 */
allowedApps: string[]
/** 最大消息大小(字节) */
maxMessageSize: number
/** 消息保留时间(毫秒) */
messageRetention: number
} }
/** /**
* 事件统计信息 * 事件统计信息
*/ */
export interface EventStatistics { export interface EventStatistics {
/** 总发送消息数 */
totalMessagesSent: number totalMessagesSent: number
/** 总接收消息数 */
totalMessagesReceived: number totalMessagesReceived: number
/** 总广播数 */
totalBroadcasts: number totalBroadcasts: number
/** 失败消息数 */
failedMessages: number failedMessages: number
/** 激活的订阅者数 */
activeSubscribers: number activeSubscribers: number
/** 通道使用情况 */
channelUsage: Map<string, number> channelUsage: Map<string, number>
} }
@@ -116,7 +163,7 @@ export interface WindowFormDataUpdateParams {
export interface EventCommunicationEvents extends IEventMap { export interface EventCommunicationEvents extends IEventMap {
// 系统就绪事件 // 系统就绪事件
onSystemReady: (data: { timestamp: Date; services: string[] }) => void onSystemReady: (data: { timestamp: Date; services: string[] }) => void
// 窗体相关事件 // 窗体相关事件
onWindowStateChanged: (windowId: string, newState: string, oldState: string) => void onWindowStateChanged: (windowId: string, newState: string, oldState: string) => void
onWindowFormDataUpdate: (data: WindowFormDataUpdateParams) => void onWindowFormDataUpdate: (data: WindowFormDataUpdateParams) => void
@@ -124,14 +171,14 @@ export interface EventCommunicationEvents extends IEventMap {
onWindowFormResizing: (windowId: string, width: number, height: number) => void onWindowFormResizing: (windowId: string, width: number, height: number) => void
onWindowFormResizeEnd: (windowId: string) => void onWindowFormResizeEnd: (windowId: string) => void
onWindowClose: (windowId: string) => void onWindowClose: (windowId: string) => void
// 应用生命周期事件 // 应用生命周期事件
onAppLifecycle: (data: { appId: string; event: string; timestamp: Date }) => void onAppLifecycle: (data: { appId: string; event: string; timestamp: Date }) => void
// 资源相关事件 // 资源相关事件
onResourceQuotaExceeded: (appId: string, resourceType: ResourceType) => void onResourceQuotaExceeded: (appId: string, resourceType: ResourceType) => void
onPerformanceAlert: (data: { type: 'memory' | 'cpu'; usage: number; limit: number }) => void onPerformanceAlert: (data: { type: 'memory' | 'cpu'; usage: number; limit: number }) => void
// 消息处理事件 // 消息处理事件
onMessageProcessed: (message: EventMessage) => void onMessageProcessed: (message: EventMessage) => void
onMessageFailed: (message: EventMessage, error: any) => void onMessageFailed: (message: EventMessage, error: any) => void
@@ -151,10 +198,12 @@ export class EventCommunicationService {
totalBroadcasts: 0, totalBroadcasts: 0,
failedMessages: 0, failedMessages: 0,
activeSubscribers: 0, activeSubscribers: 0,
channelUsage: new Map(), channelUsage: new Map()
}) })
private processingInterval: number | null = null private processingInterval: number | null = null
private lastProcessTime: number = 0
private processInterval: number = 100 // 处理间隔(毫秒)
private eventBus: IEventBuilder<EventCommunicationEvents> private eventBus: IEventBuilder<EventCommunicationEvents>
constructor(eventBus: IEventBuilder<EventCommunicationEvents>) { constructor(eventBus: IEventBuilder<EventCommunicationEvents>) {
@@ -173,7 +222,7 @@ export class EventCommunicationService {
options: { options: {
filter?: (message: EventMessage) => boolean filter?: (message: EventMessage) => boolean
priority?: MessagePriority priority?: MessagePriority
} = {}, } = {}
): string { ): string {
// 检查通道权限 // 检查通道权限
if (!this.canAccessChannel(appId, channel)) { if (!this.canAccessChannel(appId, channel)) {
@@ -189,7 +238,7 @@ export class EventCommunicationService {
filter: options.filter, filter: options.filter,
priority: options.priority || MessagePriority.NORMAL, priority: options.priority || MessagePriority.NORMAL,
createdAt: new Date(), createdAt: new Date(),
active: true, active: true
} }
this.subscribers.set(subscriberId, subscriber) this.subscribers.set(subscriberId, subscriber)
@@ -224,8 +273,11 @@ export class EventCommunicationService {
type?: MessageType type?: MessageType
expiresIn?: number // 过期时间(毫秒) expiresIn?: number // 过期时间(毫秒)
maxRetries?: number maxRetries?: number
} = {}, } = {}
): Promise<string> { ): Promise<string> {
if (this.getChannelSubscriberCount(channel) === 0) {
throw new Error(`频道 ${channel} 无订阅者`)
}
// 检查发送者权限 // 检查发送者权限
if (!this.canAccessChannel(senderId, channel)) { if (!this.canAccessChannel(senderId, channel)) {
throw new Error(`应用 ${senderId} 无权向频道 ${channel} 发送消息`) throw new Error(`应用 ${senderId} 无权向频道 ${channel} 发送消息`)
@@ -253,7 +305,7 @@ export class EventCommunicationService {
expiresAt: options.expiresIn ? new Date(now.getTime() + options.expiresIn) : undefined, expiresAt: options.expiresIn ? new Date(now.getTime() + options.expiresIn) : undefined,
status: MessageStatus.PENDING, status: MessageStatus.PENDING,
retryCount: 0, retryCount: 0,
maxRetries: options.maxRetries || 3, maxRetries: options.maxRetries || 3
} }
// 如果是点对点消息,直接发送 // 如果是点对点消息,直接发送
@@ -277,7 +329,7 @@ export class EventCommunicationService {
this.recordMessage(message) this.recordMessage(message)
console.log( console.log(
`[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`, `[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`
) )
return messageId return messageId
} }
@@ -292,11 +344,11 @@ export class EventCommunicationService {
options: { options: {
priority?: MessagePriority priority?: MessagePriority
expiresIn?: number expiresIn?: number
} = {}, } = {}
): Promise<string> { ): Promise<string> {
return this.sendMessage(senderId, channel, payload, { return this.sendMessage(senderId, channel, payload, {
...options, ...options,
type: MessageType.BROADCAST, type: MessageType.BROADCAST
}) })
} }
@@ -310,14 +362,14 @@ export class EventCommunicationService {
options: { options: {
priority?: MessagePriority priority?: MessagePriority
expiresIn?: number expiresIn?: number
} = {}, } = {}
): Promise<string> { ): Promise<string> {
const channel = 'cross-app' const channel = 'cross-app'
return this.sendMessage(senderId, channel, payload, { return this.sendMessage(senderId, channel, payload, {
...options, ...options,
receiverId, receiverId,
type: MessageType.CROSS_APP, type: MessageType.CROSS_APP
}) })
} }
@@ -330,7 +382,7 @@ export class EventCommunicationService {
channel?: string channel?: string
limit?: number limit?: number
since?: Date since?: Date
} = {}, } = {}
): EventMessage[] { ): EventMessage[] {
const history = this.messageHistory.get(appId) || [] const history = this.messageHistory.get(appId) || []
@@ -363,7 +415,7 @@ export class EventCommunicationService {
*/ */
getChannelSubscriberCount(channel: string): number { getChannelSubscriberCount(channel: string): number {
return Array.from(this.subscribers.values()).filter( return Array.from(this.subscribers.values()).filter(
(sub) => sub.channel === channel && sub.active, (sub) => sub.channel === channel && sub.active
).length ).length
} }
@@ -377,7 +429,7 @@ export class EventCommunicationService {
this.channels.set(channel, { this.channels.set(channel, {
name: channel, name: channel,
...config, ...config
}) })
console.log(`创建通信频道: ${channel}`) console.log(`创建通信频道: ${channel}`)
@@ -442,7 +494,7 @@ export class EventCommunicationService {
*/ */
destroy(): void { destroy(): void {
if (this.processingInterval) { if (this.processingInterval) {
clearInterval(this.processingInterval) cancelAnimationFrame(this.processingInterval)
this.processingInterval = null this.processingInterval = null
} }
@@ -466,7 +518,7 @@ export class EventCommunicationService {
restricted: true, restricted: true,
allowedApps: ['system'], allowedApps: ['system'],
maxMessageSize: 1024 * 10, // 10KB 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, restricted: false,
allowedApps: [], allowedApps: [],
maxMessageSize: 1024 * 100, // 100KB 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, restricted: false,
allowedApps: [], allowedApps: [],
maxMessageSize: 1024 * 5, // 5KB maxMessageSize: 1024 * 5, // 5KB
messageRetention: 60 * 60 * 1000, // 1小时 messageRetention: 60 * 60 * 1000 // 1小时
}) })
// 广播频道 // 广播频道
@@ -493,7 +545,7 @@ export class EventCommunicationService {
restricted: true, restricted: true,
allowedApps: ['system'], allowedApps: ['system'],
maxMessageSize: 1024 * 50, // 50KB 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') { if (message.channel !== 'system') {
console.warn( console.warn(
`[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`, `[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`
) )
} }
return return
@@ -570,7 +622,7 @@ export class EventCommunicationService {
await subscriber.handler(message) await subscriber.handler(message)
this.statistics.totalMessagesReceived++ this.statistics.totalMessagesReceived++
console.log( console.log(
`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`, `[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`
) )
} catch (error) { } catch (error) {
console.error(`向订阅者 ${subscriber.id} 发送消息失败:`, error) console.error(`向订阅者 ${subscriber.id} 发送消息失败:`, error)
@@ -615,10 +667,20 @@ export class EventCommunicationService {
* 开始消息处理循环 * 开始消息处理循环
*/ */
private startMessageProcessing(): void { private startMessageProcessing(): void {
this.processingInterval = setInterval(() => { const processFrame = (timestamp: number) => {
this.processMessageQueue() // 如果距离上次处理时间超过设定间隔,则处理消息
this.cleanupExpiredMessages() if (timestamp - this.lastProcessTime >= this.processInterval) {
}, 100) // 每100ms处理一次 this.processMessageQueue()
this.cleanupExpiredMessages()
this.lastProcessTime = timestamp
}
// 继续下一帧
this.processingInterval = requestAnimationFrame(processFrame)
}
// 启动处理循环
this.processingInterval = requestAnimationFrame(processFrame)
} }
/** /**
@@ -680,7 +742,7 @@ export class EventCommunicationService {
*/ */
private updateActiveSubscribersCount(): void { private updateActiveSubscribersCount(): void {
this.statistics.activeSubscribers = Array.from(this.subscribers.values()).filter( this.statistics.activeSubscribers = Array.from(this.subscribers.values()).filter(
(sub) => sub.active, (sub) => sub.active
).length ).length
} }
} }

View File

@@ -3,7 +3,7 @@ import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
import type { IEventBuilder } from '@/events/IEventBuilder' import type { IEventBuilder } from '@/events/IEventBuilder'
import type { import type {
EventCommunicationEvents, EventCommunicationEvents,
WindowFormDataUpdateParams, WindowFormDataUpdateParams
} from './EventCommunicationService' } from './EventCommunicationService'
import type { ResourceType } from './ResourceService' import type { ResourceType } from './ResourceService'
@@ -19,36 +19,26 @@ import { externalAppDiscovery } from './ExternalAppDiscovery'
* 系统服务配置接口 * 系统服务配置接口
*/ */
export interface SystemServiceConfig { export interface SystemServiceConfig {
debug?: boolean debug?: boolean // 是否开启调试模式
maxMemoryUsage?: number autoCleanup?: boolean // 是否自动清理
maxCpuUsage?: number cleanupInterval?: number // 自动清理间隔
enablePerformanceMonitoring?: boolean
enableSecurityAudit?: boolean
autoCleanup?: boolean
cleanupInterval?: number
} }
/** /**
* 系统状态接口 * 系统状态接口
*/ */
export interface SystemStatus { export interface SystemStatus {
initialized: boolean initialized: boolean // 系统是否初始化完成
running: boolean running: boolean // 系统是否运行中
servicesStatus: { servicesStatus: {
windowService: boolean windowService: boolean // 窗体服务是否启动
resourceService: boolean resourceService: boolean // 资源服务是否启动
eventService: boolean eventService: boolean // 事件服务是否启动
sandboxEngine: boolean sandboxEngine: boolean // 沙箱引擎是否启动
lifecycleManager: boolean lifecycleManager: boolean // 生命周期管理器是否启动
} }
performance: { uptime: number // 系统运行时间
memoryUsage: number lastError?: string // 最后一次错误
cpuUsage: number
activeApps: number
activeWindows: number
}
uptime: number
lastError?: string
} }
/** /**
@@ -88,15 +78,9 @@ export class SystemServiceIntegration {
resourceService: false, resourceService: false,
eventService: false, eventService: false,
sandboxEngine: false, sandboxEngine: false,
lifecycleManager: false, lifecycleManager: false
}, },
performance: { uptime: 0
memoryUsage: 0,
cpuUsage: 0,
activeApps: 0,
activeWindows: 0,
},
uptime: 0,
}) })
// 性能监控 // 性能监控
@@ -106,13 +90,9 @@ export class SystemServiceIntegration {
constructor(config: SystemServiceConfig = {}) { constructor(config: SystemServiceConfig = {}) {
this.config = { this.config = {
debug: false, debug: false,
maxMemoryUsage: 1024, // 1GB
maxCpuUsage: 80, // 80%
enablePerformanceMonitoring: true,
enableSecurityAudit: true,
autoCleanup: true, autoCleanup: true,
cleanupInterval: 5 * 60 * 1000, // 5分钟 cleanupInterval: 5 * 60 * 1000, // 5分钟
...config, ...config
} }
this.startTime = new Date() this.startTime = new Date()
@@ -141,11 +121,6 @@ export class SystemServiceIntegration {
// 设置SDK消息处理 // 设置SDK消息处理
this.setupSDKMessageHandling() this.setupSDKMessageHandling()
// 启动性能监控
if (this.config.enablePerformanceMonitoring) {
this.startPerformanceMonitoring()
}
// 启动自动清理 // 启动自动清理
if (this.config.autoCleanup) { if (this.config.autoCleanup) {
this.startAutoCleanup() this.startAutoCleanup()
@@ -167,7 +142,7 @@ export class SystemServiceIntegration {
// 发送系统就绪事件 // 发送系统就绪事件
this.eventService.sendMessage('system', 'system-ready', { this.eventService.sendMessage('system', 'system-ready', {
timestamp: new Date(), timestamp: new Date(),
services: Object.keys(this.systemStatus.servicesStatus), services: Object.keys(this.systemStatus.servicesStatus)
}) })
} catch (error) { } catch (error) {
console.error('系统服务初始化失败:', error) console.error('系统服务初始化失败:', error)
@@ -180,7 +155,6 @@ export class SystemServiceIntegration {
* 获取系统状态 * 获取系统状态
*/ */
getSystemStatus(): SystemStatus { getSystemStatus(): SystemStatus {
this.updateSystemStatus()
return { ...this.systemStatus } return { ...this.systemStatus }
} }
@@ -240,7 +214,7 @@ export class SystemServiceIntegration {
return { return {
success: true, success: true,
data: result, data: result,
requestId, requestId
} }
} catch (error) { } catch (error) {
console.error('SDK调用失败:', error) console.error('SDK调用失败:', error)
@@ -248,7 +222,7 @@ export class SystemServiceIntegration {
return { return {
success: false, success: false,
error: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error.message : String(error),
requestId, requestId
} }
} }
} }
@@ -324,8 +298,6 @@ export class SystemServiceIntegration {
console.log('系统服务已关闭') console.log('系统服务已关闭')
} }
// 私有方法
/** /**
* 初始化所有服务 * 初始化所有服务
*/ */
@@ -356,7 +328,7 @@ export class SystemServiceIntegration {
this.windowService, this.windowService,
this.resourceService, this.resourceService,
this.eventService, this.eventService,
this.sandboxEngine, this.sandboxEngine
) )
this.systemStatus.servicesStatus.lifecycleManager = true this.systemStatus.servicesStatus.lifecycleManager = true
} }
@@ -380,15 +352,15 @@ export class SystemServiceIntegration {
'onWindowStateChanged', 'onWindowStateChanged',
(windowId: string, newState: string, oldState: string) => { (windowId: string, newState: string, oldState: string) => {
console.log( console.log(
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`, `[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`
) )
this.eventService.sendMessage('system', 'window-state-change', { this.eventService.sendMessage('system', 'window-state-change', {
windowId, windowId,
newState, newState,
oldState, oldState
}) })
console.log(`[SystemIntegration] 已发送 window-state-change 消息到事件通信服务`) console.log(`[SystemIntegration] 已发送 window-state-change 消息到事件通信服务`)
}, }
) )
// 监听窗体关闭事件,自动停止对应的应用 // 监听窗体关闭事件,自动停止对应的应用
@@ -412,24 +384,13 @@ export class SystemServiceIntegration {
// 监听窗体数据更新事件 // 监听窗体数据更新事件
this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => { this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => {
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data) console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
// 只有在有订阅者时才发送消息 this.eventService.sendMessage('system', 'window-form-data-update', 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) => { this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => {
console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`) console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`)
// 只有在有订阅者时才发送消息 this.eventService.sendMessage('system', 'window-form-resize-start', { 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) => { (windowId: string, width: number, height: number) => {
console.log(`[SystemIntegration] 接收到窗体调整尺寸过程中事件: ${windowId}`, { console.log(`[SystemIntegration] 接收到窗体调整尺寸过程中事件: ${windowId}`, {
width, width,
height, height
}) })
// 只有在有订阅者时才发送消息 this.eventService.sendMessage('system', 'window-form-resizing', {
if (this.eventService.getChannelSubscriberCount('window-form-resizing') > 0) { windowId,
this.eventService.sendMessage('system', 'window-form-resizing', { width,
windowId, height
width, })
height, }
})
} else {
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-resizing 消息`)
}
},
) )
// 监听窗体调整尺寸结束事件 // 监听窗体调整尺寸结束事件
this.eventBus.addEventListener('onWindowFormResizeEnd', (windowId: string) => { this.eventBus.addEventListener('onWindowFormResizeEnd', (windowId: string) => {
console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`) console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`)
// 只有在有订阅者时才发送消息 this.eventService.sendMessage('system', 'window-form-resize-end', { 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( iframe.contentWindow?.postMessage(
{ {
type: 'system:response', type: 'system:response',
...result, ...result
}, },
'*', '*'
) )
} }
} }
@@ -567,9 +506,9 @@ export class SystemServiceIntegration {
type: 'system:storage-response', type: 'system:storage-response',
requestId, requestId,
result, result,
success, success
}, },
'*', '*'
) )
} }
} }
@@ -660,7 +599,7 @@ export class SystemServiceIntegration {
const windowData = this.windowService.getWindow(windowId) const windowData = this.windowService.getWindow(windowId)
return { return {
width: windowData?.config.width, width: windowData?.config.width,
height: windowData?.config.height, height: windowData?.config.height
} }
default: default:
@@ -714,7 +653,7 @@ export class SystemServiceIntegration {
status: response.status, status: response.status,
statusText: response.statusText, statusText: response.statusText,
headers: {} as Record<string, string>, // 简化headers处理 headers: {} as Record<string, string>, // 简化headers处理
url: response.url, url: response.url
} }
: null : null
@@ -726,7 +665,7 @@ export class SystemServiceIntegration {
return { return {
requestCount: requests.length, requestCount: requests.length,
failureCount: requests.filter((r) => r.status && r.status >= 400).length, failureCount: requests.filter((r) => r.status && r.status >= 400).length,
averageTime: 0, // 需要实现时间统计 averageTime: 0 // 需要实现时间统计
} }
default: default:
@@ -750,7 +689,7 @@ export class SystemServiceIntegration {
this.sandboxEngine.sendMessage(app.sandboxId, { this.sandboxEngine.sendMessage(app.sandboxId, {
type: 'system:event', type: 'system:event',
subscriptionId: data.subscriptionId, subscriptionId: data.subscriptionId,
message, message
}) })
} }
}) })
@@ -800,10 +739,10 @@ export class SystemServiceIntegration {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
screenResolution: { screenResolution: {
width: screen.width, width: screen.width,
height: screen.height, height: screen.height
}, },
colorDepth: screen.colorDepth, colorDepth: screen.colorDepth,
pixelRatio: window.devicePixelRatio, pixelRatio: window.devicePixelRatio
} }
case 'getAppInfo': case 'getAppInfo':
@@ -815,7 +754,7 @@ export class SystemServiceIntegration {
version: app.version, version: app.version,
permissions: app.manifest.permissions, permissions: app.manifest.permissions,
createdAt: app.installedAt, createdAt: app.installedAt,
lastActiveAt: app.lastActiveAt, lastActiveAt: app.lastActiveAt
} }
: null : null
@@ -851,32 +790,6 @@ export class SystemServiceIntegration {
return null 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!) }, 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) => { window.addEventListener('unhandledrejection', (event) => {
console.error('未处理的Promise拒绝:', event.reason) // console.error('未处理的Promise拒绝:', event.reason)
this.systemStatus.lastError = event.reason?.message || '未处理的Promise拒绝' this.systemStatus.lastError = event.reason?.message || '未处理的Promise拒绝'
}) })
} }

View File

@@ -13,18 +13,6 @@
{{ systemStatus.running ? '正常' : '错误' }} {{ systemStatus.running ? '正常' : '错误' }}
</span> </span>
</div> </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> <button @click="showSystemStatus = false" class="close-btn">关闭</button>
</div> </div>
</div> </div>
@@ -68,12 +56,6 @@ const systemStatus = ref<SystemStatus>({
sandboxEngine: false, sandboxEngine: false,
lifecycleManager: false lifecycleManager: false
}, },
performance: {
memoryUsage: 0,
cpuUsage: 0,
activeApps: 0,
activeWindows: 0
},
uptime: 0 uptime: 0
}) })
@@ -153,7 +135,7 @@ const startApp = async (appId: string) => {
} else if (externalAppDiscovery.hasApp(appId)) { } else if (externalAppDiscovery.hasApp(appId)) {
// 外置应用直接使用ApplicationLifecycleManager // 外置应用直接使用ApplicationLifecycleManager
console.log(`启动外置应用: ${appId}`) console.log(`启动外置应用: ${appId}`)
if (!lifecycleManager.isAppRunning(appId)) { if (!lifecycleManager.isAppRunning(appId)) {
await lifecycleManager.startApp(appId) await lifecycleManager.startApp(appId)
console.log(`外置应用 ${appId} 启动成功`) console.log(`外置应用 ${appId} 启动成功`)
@@ -189,7 +171,7 @@ onMounted(async () => {
// 开始系统状态更新 // 开始系统状态更新
statusUpdateInterval = setInterval(updateSystemStatus, 5000) statusUpdateInterval = setInterval(updateSystemStatus, 5000)
updateSystemStatus() updateSystemStatus()
// 不再设置自动刷新定时器,只在需要时手动刷新 // 不再设置自动刷新定时器,只在需要时手动刷新
}) })