import socket from '@ohos.net.socket' import { BusinessError } from '@ohos.base' import { TCPTag } from '../config' export default class TcpClient { private static instance: TcpClient private localIp: string = '' private localIpPort: string = '' private oppositeIp: string = '' private oppositeIpPort: string = '' private tcpSendNum: number = 0 private tcp: socket.TCPSocket = socket.constructTCPSocketInstance() private events: Array = [] constructor() { if (!TcpClient.instance) { TcpClient.instance = this } return TcpClient.instance } // 初始化tcp连接 async init(tcpLocalIp: string, tcpLocalIpPort: string, tcpOppositeIp: string, tcpOppositePort: string) { this.localIp = tcpLocalIp this.oppositeIp = tcpOppositeIp this.localIpPort = tcpLocalIpPort this.oppositeIpPort = tcpOppositePort console.log(TCPTag, 'new Tcp', this.localIp, this.localIpPort, this.oppositeIp, this.oppositeIpPort) this.tcp = socket.constructTCPSocketInstance(); await this.bindTcp() await this.connectTcp() } // 绑定tcp bindTcp(): Promise { return new Promise((resolve, reject) => { this.tcp.bind({ address: this.localIp, port: Number(this.localIpPort), family: 1 }).then(() => { console.log(TCPTag, 'bindTcp success:', this.localIp, this.localIpPort, this.oppositeIp, this.oppositeIpPort) resolve(true) }).catch((err: BusinessError) => { console.log(TCPTag, 'bindTcp error:', JSON.stringify(err), this.localIp, this.localIpPort, this.oppositeIp, this.oppositeIpPort) reject(err) }) }) } // 连接tcp connectTcp(): Promise { return new Promise((resolve, reject) => { this.tcp.connect({ address: { address: this.oppositeIp, port: Number(this.oppositeIpPort), family: 1 }, timeout: 1000 * 15 }) .then(() => { this.getMessage() console.log(TCPTag, "tcp connect success") return this.tcp.setExtraOptions({ keepAlive: true }) }) .then(() => { resolve(true) }) .catch((err: BusinessError) => { console.log(TCPTag, "tcp connect or keepAlive error: ", JSON.stringify(err)) console.log(TCPTag, "tcp 重启服务") reject(err) }) }) } getMessage() { this.tcp.on("message", value => { let data = new DataView(value.message) this.events.forEach(cb => { cb(value.message.slice(5, data.byteLength)) }) }) } // 重新绑定tcp async reBind() { await this.close() this.tcp = socket.constructTCPSocketInstance(); await this.bindTcp() await this.connectTcp() } // 监听tcp错误 onError(callback: Function) { this.tcp.on('error', err => { console.log(TCPTag, 'tcp on error: ', JSON.stringify(err)) callback?.() }); } // 关闭tcp连接 close(): Promise { return this.tcp?.close() } // 监听tcp消息 onMsg(callback: Function) { this.events.push(callback) } // 接收tcp消息 sendMsg(data: string): Promise { return this.tcp?.send({ data }).catch(async (err: BusinessError) => { console.log(TCPTag, 'sendMsg error:', JSON.stringify(err)) this.tcpSendNum++ if (this.tcpSendNum > 10) { this.tcpSendNum = 0 await this.reBind() } return Promise.reject(err) }) } // 取消监听tcp消息 offMsg(callback: Function) { this.events = this.events.filter(cb => cb !== callback) } }