2025-09-28 17:37:28 +08:00
|
|
|
import Logger from './Logger';
|
2025-09-26 11:11:56 +08:00
|
|
|
import { TaskPool } from './TaskPool';
|
|
|
|
|
import { WebsocketClient } from './WebsocketUtils';
|
2025-09-28 17:37:28 +08:00
|
|
|
import { util } from '@kit.ArkTS';
|
2025-09-26 11:11:56 +08:00
|
|
|
|
|
|
|
|
const Tag = "CommandService"
|
|
|
|
|
|
2025-09-28 17:37:28 +08:00
|
|
|
interface Message<T = Object> {
|
|
|
|
|
type: CommandType
|
2025-09-26 11:11:56 +08:00
|
|
|
reqCode: string
|
2025-09-28 17:37:28 +08:00
|
|
|
body: T
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface HandleAlarmBody {
|
|
|
|
|
alarmId: string
|
|
|
|
|
handleInfo: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface CommandBody {
|
|
|
|
|
lineId: string
|
|
|
|
|
code: string
|
|
|
|
|
name: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ResponseMessage {
|
|
|
|
|
code: string
|
|
|
|
|
msg: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum CommandType {
|
|
|
|
|
HandleAlarm = "handleAlarm",
|
|
|
|
|
PostCmd = "PostCmd"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum CommandCode {
|
|
|
|
|
GetHomePosition = 'getHomePosition',
|
|
|
|
|
ToHomePosition = 'toHomePosition',
|
|
|
|
|
GetChargePosition = 'getChargePosition',
|
|
|
|
|
ToChargePosition = 'toChargePosition',
|
|
|
|
|
GetScanPosition = 'getScanPosition',
|
|
|
|
|
ToScanPosition = 'toScanPosition',
|
2025-09-26 11:11:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class CommandService {
|
|
|
|
|
private service?: WebsocketClient
|
|
|
|
|
private taskPool: TaskPool<boolean> = new TaskPool()
|
|
|
|
|
private static instance: CommandService
|
2025-09-28 17:37:28 +08:00
|
|
|
private tick: number = -1
|
|
|
|
|
private commandCallback: Map<string, Function> = new Map()
|
2025-09-26 11:11:56 +08:00
|
|
|
|
|
|
|
|
constructor(url: string) {
|
|
|
|
|
if (!CommandService.instance) {
|
|
|
|
|
this.service = new WebsocketClient(url, this.deal)
|
|
|
|
|
CommandService.instance = this
|
|
|
|
|
}
|
|
|
|
|
return CommandService.instance
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-28 17:37:28 +08:00
|
|
|
private deal(message: string) {
|
|
|
|
|
if (message === "pong") {
|
|
|
|
|
Logger.info("心跳回应")
|
|
|
|
|
return ""
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
let response: Message<ResponseMessage> = JSON.parse(message)
|
|
|
|
|
if (response.type === CommandType.PostCmd) {
|
|
|
|
|
this.commandCallback.get(response.reqCode)?.(response.body)
|
|
|
|
|
this.commandCallback.delete(response.reqCode)
|
|
|
|
|
}
|
|
|
|
|
return message
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Logger.error(Tag, "解析报文出错", JSON.stringify(e))
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-26 11:11:56 +08:00
|
|
|
}
|
|
|
|
|
|
2025-09-28 17:37:28 +08:00
|
|
|
private send(message: Message) {
|
|
|
|
|
return new Promise<void | ResponseMessage>((resolve, reject) => {
|
2025-09-26 11:11:56 +08:00
|
|
|
this.taskPool.add({
|
|
|
|
|
execute: () => {
|
2025-09-28 17:37:28 +08:00
|
|
|
if (message.type === CommandType.PostCmd) {
|
|
|
|
|
return new Promise<boolean>((_resolve, _reject) => {
|
|
|
|
|
this.service!.send(JSON.stringify(message)).then(() => {
|
2025-09-28 17:44:00 +08:00
|
|
|
this.commandCallback.set(message.reqCode, (res: ResponseMessage) => resolve(res))
|
2025-09-28 17:37:28 +08:00
|
|
|
_resolve(true)
|
|
|
|
|
}).catch(_reject)
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
return this.service!.send(JSON.stringify(message))
|
|
|
|
|
}
|
2025-09-26 11:11:56 +08:00
|
|
|
},
|
|
|
|
|
repair: (): Promise<void> => {
|
|
|
|
|
return this.service!.reconnect();
|
|
|
|
|
},
|
|
|
|
|
success: () => {
|
|
|
|
|
resolve()
|
|
|
|
|
},
|
|
|
|
|
error: () => {
|
|
|
|
|
reject()
|
|
|
|
|
},
|
|
|
|
|
retryCount: 5
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-28 17:37:28 +08:00
|
|
|
init() {
|
|
|
|
|
return new Promise<void>((resolve, reject) => {
|
|
|
|
|
this.service!.connect().then(() => {
|
|
|
|
|
this.tick = setInterval(() => {
|
|
|
|
|
this.service?.send("ping")
|
|
|
|
|
}, 1000 * 15)
|
|
|
|
|
resolve()
|
|
|
|
|
}).catch(reject)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subscribe(cb: Function) {
|
|
|
|
|
this.service!.subscribe(cb)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsubscribe(cb: Function) {
|
|
|
|
|
this.service!.unsubscribe(cb)
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-26 11:11:56 +08:00
|
|
|
close(): Promise<boolean> {
|
2025-09-28 17:37:28 +08:00
|
|
|
clearInterval(this.tick)
|
2025-09-26 11:11:56 +08:00
|
|
|
return this.service!.close()
|
|
|
|
|
}
|
2025-09-28 17:37:28 +08:00
|
|
|
|
|
|
|
|
submitAlarm(alarmId: string, handleInfo: string): Promise<void> {
|
|
|
|
|
let handleBody: HandleAlarmBody = {
|
|
|
|
|
alarmId,
|
|
|
|
|
handleInfo
|
|
|
|
|
}
|
|
|
|
|
return this.send({
|
|
|
|
|
type: CommandType.HandleAlarm,
|
|
|
|
|
reqCode: util.generateRandomUUID(true),
|
|
|
|
|
body: handleBody
|
|
|
|
|
}) as Promise<void>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
submitCommand(lineId: string, code: CommandCode, name: string): Promise<ResponseMessage> {
|
|
|
|
|
let commandBody: CommandBody = {
|
|
|
|
|
lineId,
|
|
|
|
|
code,
|
|
|
|
|
name
|
|
|
|
|
}
|
|
|
|
|
return this.send({
|
|
|
|
|
type: CommandType.PostCmd,
|
|
|
|
|
reqCode: util.generateRandomUUID(true),
|
|
|
|
|
body: commandBody
|
|
|
|
|
}) as Promise<ResponseMessage>
|
|
|
|
|
}
|
2025-09-26 11:11:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const commandService =
|
|
|
|
|
new CommandService("ws://testdevice.duolunxc.com/car-inspection-rest/websocket/pad?deviceNo=666666")
|