import type Viewport from '@/core/engine/Viewport.ts' import { worldModel } from '@/core/manager/WorldModel.ts' import mqtt, { type IConnackPacket, type IPublishPacket } from 'mqtt' import type { ErrorWithReasonCode } from 'mqtt/src/lib/shared.ts' import type Cl23dObject from '@/modules/cl2/Cl23dObject.ts' import { Request } from '@ease-forge/shared' import AmrMessageManager from '@/core/manager/amr/AmrMessageManager' import { AmrMsg } from '@/core/manager/amr/AmrMessageDefine' export default class EnvManager { private viewport: Viewport private amrMessageManager: AmrMessageManager = new AmrMessageManager() public client: mqtt.MqttClient = null onMqttConnect = (packet: IConnackPacket) => { console.log('Connected') } onMqttMessage = (topic: string, payload: Buffer, packet: IPublishPacket) => { console.log(`[${topic}]-> ${payload.toString()}`) if (topic.startsWith('/wcs_server/')) { const message: AmrMsg = JSON.parse(payload.toString()) this.amrMessageManager.handleMessage(topic, message) } else { } } onMqttError = (error: Error | ErrorWithReasonCode) => { console.error('Error:', error) } async start(env: EnvInfo) { if (!env) { system.showErrorDialog('Environment is not specified, cannot start EnvManager.') return } if (!worldModel.state.isOpened) { system.showErrorDialog('WorldModel is not opened, cannot start EnvManager.') return } if (!worldModel.state.runState.currentEnvId) { system.showErrorDialog('Current environment ID is not set, cannot start EnvManager.') return } if (worldModel.state.runState.isRunning) { system.showErrorDialog('EnvManager is already running, cannot start again.') return } if (!env.envConfig.mqtt.websocket) { system.showErrorDialog('MQTT websocket URL is not set in the envConfig.mqtt.') return } if (!env.envConfig.frontendMqtt.websocket) { system.showErrorDialog('Frontend MQTT websocket URL is not set in the envConfig.frontendMqtt.') return } await this.stop() system.showLoading() worldModel.state.runState.isLoading = true worldModel.state.runState.currentEnv = env try { await LCC.serverStart() await worldModel.lccMqttManager.start(env.envConfig.frontendMqtt) await LCC.loadInv() this.client = mqtt.connect(env.envConfig.mqtt.websocket, { path: '/mqtt', clientId: system.createUUID(), clean: true, connectTimeout: 300, username: env.envConfig.mqtt.username, password: env.envConfig.mqtt.password, unixSocket: true, keepalive: 60 }) await LCC.loadExecutor() this.client.on('connect', this.onMqttConnect) this.client.on('message', this.onMqttMessage) this.client.on('error', this.onMqttError) worldModel.state.runState.isRunning = true } finally { system.clearLoading() worldModel.state.runState.isLoading = false } } async stop() { system.showLoading() try { if (window['LCC']) { await LCC.serverStop() } worldModel.state.runState.isRunning = false if (this.client) { this.client.removeAllListeners() this.client.end() this.client = null } this.clearExecutors() this.clearInv() this.viewport?.runtimeManager?.clear() } finally { system.clearLoading() worldModel.state.runState.isLoading = false } } clearInv() { } clearExecutors() { } /** * 创建运行环境 * @param worldId 世界ID */ static async createEnv(worldId: string) { throw new Error('Method not implemented.') } /** * 获取所有运行环境 */ static async getAllEnv(worldId: string): Promise> { // system.invokeServer('') if (!worldId) { return Promise.resolve({ success: true, data: [], msg: '' }) } const res = await Request.request.post('/api/workbench/EnvController@getAllEnv', { worldId: worldId }) return res.data } /** * 卸载资源 */ dispose(): void { this.stop() } }