152 lines
4.2 KiB
Plaintext
152 lines
4.2 KiB
Plaintext
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<Function> = []
|
|
// 连接状态是否成功
|
|
private linkStatus: boolean = false
|
|
|
|
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<Boolean> {
|
|
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<Boolean> {
|
|
return new Promise((resolve, reject) => {
|
|
this.tcp.connect({
|
|
address: {
|
|
address: this.oppositeIp, port: Number(this.oppositeIpPort), family: 1
|
|
}, timeout: 1000 * 15
|
|
})
|
|
.then(() => {
|
|
this.linkStatus = true
|
|
this.getMessage()
|
|
console.log(TCPTag, "tcp connect success")
|
|
return this.tcp.setExtraOptions({
|
|
keepAlive: true
|
|
})
|
|
})
|
|
.then(() => {
|
|
resolve(true)
|
|
})
|
|
.catch((err: BusinessError) => {
|
|
this.linkStatus = false
|
|
console.log(TCPTag, "tcp connect or keepAlive error: ", JSON.stringify(err))
|
|
console.log(TCPTag, "tcp 重启服务")
|
|
reject(err)
|
|
})
|
|
})
|
|
}
|
|
|
|
getMessage() {
|
|
if (!this.linkStatus) {
|
|
console.log(TCPTag, '不允许获取消息: TCP未连接');
|
|
return;
|
|
}
|
|
this.tcp.on("message", value => {
|
|
let data = new DataView(value.message)
|
|
this.events.forEach(cb => {
|
|
// TODO
|
|
// 一体机不需要截取
|
|
cb(value.message.slice(5, data.byteLength))
|
|
})
|
|
})
|
|
}
|
|
|
|
// 重新绑定tcp
|
|
async reBind() {
|
|
console.log(TCPTag, 'tcp 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<void> {
|
|
return this.tcp?.close()
|
|
}
|
|
|
|
// 监听tcp消息
|
|
onMsg(callback: Function) {
|
|
if (this.events.includes(callback)) {
|
|
console.log(TCPTag, '已经存在这个获取消息方法了');
|
|
return;
|
|
}
|
|
this.events.push(callback);
|
|
}
|
|
|
|
// 接收tcp消息
|
|
sendMsg(data: string): Promise<void> {
|
|
if (!this.linkStatus) {
|
|
console.log(TCPTag, '不允许发送: TCP未连接');
|
|
return Promise.reject(new Error('TCP connection is not established'));
|
|
}
|
|
return this.tcp?.send({
|
|
data
|
|
}).catch(async (err: BusinessError) => {
|
|
console.log(TCPTag, 'sendMsg error:', JSON.stringify(err), this.oppositeIp, this.oppositeIpPort)
|
|
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)
|
|
}
|
|
}
|