158 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| import Logger from './Logger';
 | |
| import { TaskPool } from './TaskPool';
 | |
| import { WebsocketClient } from './WebsocketUtils';
 | |
| import { util } from '@kit.ArkTS';
 | |
| 
 | |
| const Tag = "CommandService"
 | |
| 
 | |
| interface Message<T = Object> {
 | |
|   type: CommandType
 | |
|   reqCode: string
 | |
|   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',
 | |
| }
 | |
| 
 | |
| export class CommandService {
 | |
|   private service?: WebsocketClient
 | |
|   private taskPool: TaskPool<boolean> = new TaskPool()
 | |
|   private static instance: CommandService
 | |
|   private tick: number = -1
 | |
|   private commandCallback: Map<string, Function> = new Map()
 | |
| 
 | |
|   constructor(url: string) {
 | |
|     if (!CommandService.instance) {
 | |
|       this.service = new WebsocketClient(url, this.deal)
 | |
|       CommandService.instance = this
 | |
|     }
 | |
|     return CommandService.instance
 | |
|   }
 | |
| 
 | |
|   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 ""
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   private send(message: Message) {
 | |
|     return new Promise<void | ResponseMessage>((resolve, reject) => {
 | |
|       this.taskPool.add({
 | |
|         execute: () => {
 | |
|           if (message.type === CommandType.PostCmd) {
 | |
|             return new Promise<boolean>((_resolve, _reject) => {
 | |
|               this.service!.send(JSON.stringify(message)).then(() => {
 | |
|                 this.commandCallback.set(message.reqCode, (res: ResponseMessage) => resolve(res))
 | |
|                 _resolve(true)
 | |
|               }).catch(_reject)
 | |
|             })
 | |
|           } else {
 | |
|             return this.service!.send(JSON.stringify(message))
 | |
|           }
 | |
|         },
 | |
|         repair: (): Promise<void> => {
 | |
|           return this.service!.reconnect();
 | |
|         },
 | |
|         success: () => {
 | |
|           resolve()
 | |
|         },
 | |
|         error: () => {
 | |
|           reject()
 | |
|         },
 | |
|         retryCount: 5
 | |
|       })
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   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)
 | |
|   }
 | |
| 
 | |
|   close(): Promise<boolean> {
 | |
|     clearInterval(this.tick)
 | |
|     return this.service!.close()
 | |
|   }
 | |
| 
 | |
|   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>
 | |
|   }
 | |
| }
 | |
| 
 | |
| export const commandService =
 | |
|   new CommandService("ws://testdevice.duolunxc.com/car-inspection-rest/websocket/pad?deviceNo=666666") |