2025-04-10 10:28:07 +08:00
|
|
|
import socket from '@ohos.net.socket'
|
|
|
|
|
import { UDPTag } from '../config'
|
2025-06-11 17:50:37 +08:00
|
|
|
import { FillZero, StringToASCII } from './Common'
|
2025-08-19 16:54:10 +08:00
|
|
|
import { BusinessError } from '@ohos.base'
|
2025-10-16 17:47:48 +08:00
|
|
|
import { dConsole } from './LogWorker'
|
2025-04-10 10:28:07 +08:00
|
|
|
|
|
|
|
|
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 {
|
2025-06-11 17:50:37 +08:00
|
|
|
protected udp: socket.UDPSocket | null = null
|
2025-04-10 10:28:07 +08:00
|
|
|
private localIp: string = ''
|
|
|
|
|
private localIpPort: string = ''
|
|
|
|
|
private oppositeIp: string = ''
|
|
|
|
|
private oppositeIpPort: string = ''
|
|
|
|
|
private messageEvents: Array<Function> = []
|
|
|
|
|
private errorEvents: Array<Function> = []
|
|
|
|
|
private dealMethod?: DealMethod<object>
|
2025-07-22 14:26:37 +08:00
|
|
|
// 连接状态
|
|
|
|
|
private linkStatus: boolean = false
|
2025-04-10 10:28:07 +08:00
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 绑定udp连接
|
2025-04-10 10:28:07 +08:00
|
|
|
bindUdp(): Promise<void> | undefined {
|
2025-06-11 17:50:37 +08:00
|
|
|
console.log(UDPTag, "绑定udp", this.localIp, this.localIpPort)
|
2025-04-10 10:28:07 +08:00
|
|
|
return this.udp?.bind({
|
|
|
|
|
address: this.localIp, port: parseInt(this.localIpPort), family: 1
|
2025-04-14 14:35:18 +08:00
|
|
|
}).then(res => {
|
|
|
|
|
console.log(UDPTag, "udp 绑定成功!", JSON.stringify(res))
|
2025-04-10 10:28:07 +08:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 重新绑定udp连接
|
2025-04-10 10:28:07 +08:00
|
|
|
async reBind() {
|
|
|
|
|
await this.close()
|
|
|
|
|
this.udp = socket.constructUDPSocketInstance();
|
|
|
|
|
this.bindEvent()
|
|
|
|
|
await this.bindUdp()
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 关闭udp连接
|
2025-04-10 10:28:07 +08:00
|
|
|
close(): Promise<void> | undefined {
|
|
|
|
|
this.messageEvents = []
|
|
|
|
|
this.errorEvents = []
|
|
|
|
|
this.dealMethod = undefined
|
|
|
|
|
this.udp?.off("message")
|
|
|
|
|
this.udp?.off("error")
|
|
|
|
|
return this.udp?.close()
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 设置处理消息的函数
|
2025-04-10 10:28:07 +08:00
|
|
|
setDealMethod<T extends Object>(fun: DealMethod<T>) {
|
|
|
|
|
this.dealMethod = fun
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 发送消息
|
2025-04-10 10:28:07 +08:00
|
|
|
sendMsg(data: ArrayBuffer | string): Promise<void> | undefined {
|
|
|
|
|
return this.udp?.send({
|
|
|
|
|
data,
|
|
|
|
|
address: {
|
|
|
|
|
address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1
|
|
|
|
|
}
|
2025-04-14 14:35:18 +08:00
|
|
|
}).then(res => {
|
2025-10-17 10:02:17 +08:00
|
|
|
// console.log(UDPTag, "udp发送成功", JSON.stringify(res))
|
2025-08-19 16:54:10 +08:00
|
|
|
}).catch((e: BusinessError) => {
|
|
|
|
|
console.error(UDPTag, "udp发送失败", JSON.stringify(e))
|
2025-04-10 10:28:07 +08:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 组装消息
|
2025-04-10 10:28:07 +08:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 发送消息
|
2025-04-10 10:28:07 +08:00
|
|
|
sendMsgExt(param: MsgExt) {
|
2025-10-16 17:47:48 +08:00
|
|
|
dConsole.info(UDPTag, "小红球数据", param)
|
2025-04-10 10:28:07 +08:00
|
|
|
const msgData = this.setWholeMsg(param)
|
|
|
|
|
this.sendMsg(msgData)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 创建udp实例
|
2025-04-10 10:28:07 +08:00
|
|
|
async create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
|
2025-04-14 14:35:18 +08:00
|
|
|
console.log(UDPTag, "udp 初始化参数", udpLocalIp, udpLocalIpPort, udpOppositeIp, udpOppositeIpPort)
|
2025-04-10 10:28:07 +08:00
|
|
|
await this.close()
|
|
|
|
|
this.localIp = udpLocalIp
|
|
|
|
|
this.oppositeIp = udpOppositeIp
|
|
|
|
|
this.localIpPort = udpLocalIpPort
|
|
|
|
|
this.oppositeIpPort = udpOppositeIpPort
|
2025-04-14 14:35:18 +08:00
|
|
|
try {
|
|
|
|
|
this.udp = socket.constructUDPSocketInstance();
|
2025-04-14 10:59:37 +08:00
|
|
|
this.bindUdp()
|
|
|
|
|
this.bindEvent()
|
|
|
|
|
} catch (e) {
|
2025-04-14 14:35:18 +08:00
|
|
|
console.log(UDPTag, "udp错误", JSON.stringify(e))
|
2025-04-14 10:59:37 +08:00
|
|
|
}
|
2025-04-10 10:28:07 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 绑定消息事件
|
2025-04-10 10:28:07 +08:00
|
|
|
onMsg(callback: Function) {
|
2025-06-11 17:50:37 +08:00
|
|
|
if (this.messageEvents.findIndex(cb => cb === callback) !== -1) {
|
2025-04-10 10:28:07 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.messageEvents.push(callback)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 绑定错误事件
|
2025-04-10 10:28:07 +08:00
|
|
|
onError(callback: Function) {
|
|
|
|
|
this.errorEvents.push(callback)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 17:50:37 +08:00
|
|
|
// 取消绑定事件
|
2025-04-10 10:28:07 +08:00
|
|
|
offMsg(callback: Function) {
|
|
|
|
|
this.messageEvents = this.messageEvents.filter(cb => cb !== callback)
|
|
|
|
|
}
|
2025-06-11 17:50:37 +08:00
|
|
|
|
|
|
|
|
// 绑定事件
|
|
|
|
|
private bindEvent() {
|
|
|
|
|
this.udp?.on("message", value => {
|
|
|
|
|
let result = this.dealMethod?.(value.message)
|
2025-10-15 10:31:18 +08:00
|
|
|
// console.log(UDPTag, "udp获取消息", result)
|
2025-06-11 17:50:37 +08:00
|
|
|
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)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
2025-04-10 10:28:07 +08:00
|
|
|
}
|
|
|
|
|
|