2025-10-17 10:03:02 +08:00

163 lines
4.4 KiB
Plaintext

import socket from '@ohos.net.socket'
import { UDPTag } from '../config'
import { FillZero, StringToASCII } from './Common'
import { BusinessError } from '@ohos.base'
import { dConsole } from './LogWorker'
interface MsgExt {
id: number,
list: number[],
carNo: string,
placeId: string,
}
function generateHead(param: MsgExt): number[] {
let lshNo = AppStorage.get<string>("lsh")
let a = new Uint16Array(StringToASCII(`${param.id}${FillZero(param.placeId, 3)}`))
let b = new Uint32Array(StringToASCII(`${FillZero(param.carNo, 4)}${lshNo}`))
let c = new Uint16Array(param.list.length)
return [...a, ...b, ...c];
}
function exclusive(target: number[]): number[] {
let result = target[0]
for (let i = 1; i < target.length; i++) {
result = result ^ target[i]
}
return [result];
}
type DealMethod<T extends Object> = (value: ArrayBuffer) => T
export default class UdpClient {
protected udp: socket.UDPSocket | null = null
private localIp: string = ''
private localIpPort: string = ''
private oppositeIp: string = ''
private oppositeIpPort: string = ''
private messageEvents: Array<Function> = []
private errorEvents: Array<Function> = []
private dealMethod?: DealMethod<object>
// 连接状态
private linkStatus: boolean = false
// 绑定udp连接
bindUdp(): Promise<void> | undefined {
console.log(UDPTag, "绑定udp", this.localIp, this.localIpPort)
return this.udp?.bind({
address: this.localIp, port: parseInt(this.localIpPort), family: 1
}).then(res => {
console.log(UDPTag, "udp 绑定成功!", JSON.stringify(res))
})
}
// 重新绑定udp连接
async reBind() {
await this.close()
this.udp = socket.constructUDPSocketInstance();
this.bindEvent()
await this.bindUdp()
}
// 关闭udp连接
close(): Promise<void> | undefined {
this.messageEvents = []
this.errorEvents = []
this.dealMethod = undefined
this.udp?.off("message")
this.udp?.off("error")
return this.udp?.close()
}
// 设置处理消息的函数
setDealMethod<T extends Object>(fun: DealMethod<T>) {
this.dealMethod = fun
}
// 发送消息
sendMsg(data: ArrayBuffer | string): Promise<void> | undefined {
return this.udp?.send({
data,
address: {
address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1
}
}).then(res => {
// console.log(UDPTag, "udp发送成功", JSON.stringify(res))
}).catch((e: BusinessError) => {
console.error(UDPTag, "udp发送失败", JSON.stringify(e))
})
}
// 组装消息
setWholeMsg(params: MsgExt): ArrayBuffer {
let head = generateHead(params);
let headJudge = exclusive(head);
let body = params.list;
let bodyJudge = exclusive(body);
let end = [13, 10];
const arr = [...head, ...headJudge, ...body, ...bodyJudge, ...end]
return new Uint8Array(arr).buffer
}
// 发送消息
sendMsgExt(param: MsgExt) {
dConsole.info(UDPTag, "小红球数据", param)
const msgData = this.setWholeMsg(param)
this.sendMsg(msgData)
}
// 创建udp实例
async create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
console.log(UDPTag, "udp 初始化参数", udpLocalIp, udpLocalIpPort, udpOppositeIp, udpOppositeIpPort)
await this.close()
this.localIp = udpLocalIp
this.oppositeIp = udpOppositeIp
this.localIpPort = udpLocalIpPort
this.oppositeIpPort = udpOppositeIpPort
try {
this.udp = socket.constructUDPSocketInstance();
this.bindUdp()
this.bindEvent()
} catch (e) {
console.log(UDPTag, "udp错误", JSON.stringify(e))
}
}
// 绑定消息事件
onMsg(callback: Function) {
if (this.messageEvents.findIndex(cb => cb === callback) !== -1) {
return
}
this.messageEvents.push(callback)
}
// 绑定错误事件
onError(callback: Function) {
this.errorEvents.push(callback)
}
// 取消绑定事件
offMsg(callback: Function) {
this.messageEvents = this.messageEvents.filter(cb => cb !== callback)
}
// 绑定事件
private bindEvent() {
this.udp?.on("message", value => {
let result = this.dealMethod?.(value.message)
// console.log(UDPTag, "udp获取消息", result)
this.messageEvents.forEach(cb => {
cb(result)
})
})
this.udp?.on("error", (err) => {
console.log(UDPTag, 'udp error', JSON.stringify(err))
this.errorEvents.forEach(cb => {
cb(err)
})
})
}
}