| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   private tcp: socket.TCPSocket = socket.constructTCPSocketInstance() | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   private events: Array<Function> = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     if (!TcpClient.instance) { | 
					
						
							|  |  |  |       TcpClient.instance = this | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return TcpClient.instance | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 初始化tcp连接 | 
					
						
							|  |  |  |   async init(tcpLocalIp: string, tcpLocalIpPort: string, tcpOppositeIp: string, tcpOppositePort: string) { | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |     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(); | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |     await this.bindTcp() | 
					
						
							|  |  |  |     await this.connectTcp() | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 绑定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({ | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |         address: { | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |           address: this.oppositeIp, port: Number(this.oppositeIpPort), family: 1 | 
					
						
							|  |  |  |         }, timeout: 1000 * 15 | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |         .then(() => { | 
					
						
							|  |  |  |           this.getMessage() | 
					
						
							|  |  |  |           console.log(TCPTag, "tcp connect success") | 
					
						
							|  |  |  |           return this.tcp.setExtraOptions({ | 
					
						
							|  |  |  |             keepAlive: true | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |           }) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |         .then(() => { | 
					
						
							|  |  |  |           resolve(true) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch((err: BusinessError) => { | 
					
						
							|  |  |  |           console.log(TCPTag, "tcp connect or keepAlive error: ", JSON.stringify(err)) | 
					
						
							|  |  |  |           console.log(TCPTag, "tcp 重启服务") | 
					
						
							|  |  |  |           reject(err) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   getMessage() { | 
					
						
							|  |  |  |     this.tcp.on("message", value => { | 
					
						
							|  |  |  |       let data = new DataView(value.message) | 
					
						
							|  |  |  |       this.events.forEach(cb => { | 
					
						
							|  |  |  |         cb(value.message.slice(5, data.byteLength)) | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 重新绑定tcp | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   async reBind() { | 
					
						
							|  |  |  |     await this.close() | 
					
						
							|  |  |  |     this.tcp = socket.constructTCPSocketInstance(); | 
					
						
							|  |  |  |     await this.bindTcp() | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |     await this.connectTcp() | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 监听tcp错误 | 
					
						
							|  |  |  |   onError(callback: Function) { | 
					
						
							|  |  |  |     this.tcp.on('error', err => { | 
					
						
							|  |  |  |       console.log(TCPTag, 'tcp on error: ', JSON.stringify(err)) | 
					
						
							|  |  |  |       callback?.() | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 关闭tcp连接 | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   close(): Promise<void> { | 
					
						
							|  |  |  |     return this.tcp?.close() | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 监听tcp消息 | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   onMsg(callback: Function) { | 
					
						
							|  |  |  |     this.events.push(callback) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 接收tcp消息 | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   sendMsg(data: string): Promise<void> { | 
					
						
							|  |  |  |     return this.tcp?.send({ | 
					
						
							|  |  |  |       data | 
					
						
							|  |  |  |     }).catch(async (err: BusinessError) => { | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |       console.log(TCPTag, 'sendMsg error:', JSON.stringify(err)) | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |       this.tcpSendNum++ | 
					
						
							|  |  |  |       if (this.tcpSendNum > 10) { | 
					
						
							|  |  |  |         this.tcpSendNum = 0 | 
					
						
							|  |  |  |         await this.reBind() | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return Promise.reject(err) | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-10 13:33:41 +08:00
										 |  |  |   // 取消监听tcp消息 | 
					
						
							| 
									
										
										
										
											2025-04-10 10:28:07 +08:00
										 |  |  |   offMsg(callback: Function) { | 
					
						
							|  |  |  |     this.events = this.events.filter(cb => cb !== callback) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |