Compare commits

...

8 Commits

View File

@ -2,23 +2,25 @@ import socket from '@ohos.net.socket'
import util from '@ohos.util' import util from '@ohos.util'
import promptAction from '@ohos.promptAction' import promptAction from '@ohos.promptAction'
import TcpToByte from './utils/tcp2byte' import TcpToByte from './utils/tcp2byte'
import {bytesToDecimal} from './utils/tools' import { bytesToDecimal } from './utils/tools'
const TAG = '[TCP2BYTE]' const TAG = '[TCP2BYTE]'
interface RES { interface RES {
code: number|string, code: number | string,
message?: string message?: string
} }
const config = { const config = {
address: '114.55.125.222', address: '172.37.55.191',
port: 50189 port: 40000
} }
const singleTcpClient = (function () { const singleTcpClient = (function () {
let instance; let instance;
function createInstance() { function createInstance() {
return socket.constructTCPSocketInstance() return socket.constructTCPSocketInstance()
} }
@ -34,51 +36,105 @@ const singleTcpClient = (function () {
})(); })();
export default async function tcp2ByteRequest(data): Promise<RES> { export default async function tcp2ByteRequest(data): Promise<RES> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const tcpClient: socket.TCPSocket = singleTcpClient.getClient() const tcpClient: socket.TCPSocket = singleTcpClient.getClient();
const { address, port } = config;
const tcp2Byte = new TcpToByte();
const sendData = tcp2Byte.getRequest(data);
console.info(TAG, 'sendData=>' + JSON.stringify(sendData));
const {address,port} = config // 设置超时时间(例如 10 秒)
const tcp2Byte = new TcpToByte() const timeoutDuration = 15000; // 10 秒
const sendData = tcp2Byte.getRequest(data) let timeoutHandle: number | null = null;
console.info(TAG, 'sendData=>' + JSON.stringify(sendData))
// 超时处理函数
const timeoutPromise = new Promise<RES>((_, rejectTimeout) => {
timeoutHandle = setTimeout(() => {
const errMsg = 'TCP request timed out';
console.log(TAG, "超时", errMsg);
promptAction.showToast({
message: errMsg,
duration: 3000,
});
tcpClient.close();
rejectTimeout(new Error(errMsg));
}, timeoutDuration);
});
try { try {
await tcpClient.connect({address: {address, port}}) await tcpClient.connect({
//发送消息 address: {
handSendMessage(tcpClient, data.sjbs, sendData) address,
port,
},
});
// 发送消息
handSendMessage(tcpClient, data.sjbs, sendData);
} catch (e) { } catch (e) {
console.log(TAG, 'tcp client connect error' + JSON.stringify(e)) console.log(TAG, 'tcp client connect error' + JSON.stringify(e));
promptAction.showToast({ promptAction.showToast({
message: 'tcp client connect error' + JSON.stringify(e), message: 'tcp client connect error' + JSON.stringify(e),
duration: 3000 duration: 3000,
}); });
reject(e) reject(e);
return;
} }
//收到消息 // 收到消息
tcpClient.on('message', (data) => { tcpClient.on('message', (data) => {
const res = handReceiveMessage(tcpClient, sendData, data.message) const res = handReceiveMessage(tcpClient, sendData, data.message);
if(res){ if (res) {
tcpClient.close() if (timeoutHandle) clearTimeout(timeoutHandle); // 清除超时
resolve(res) tcpClient.close();
resolve(res);
} }
}) });
tcpClient.on('error', (e) => { tcpClient.on('error', (e) => {
const errMsg = 'tcp client receive error' + JSON.stringify(e) const errMsg = 'tcp client receive error' + JSON.stringify(e);
promptAction.showToast({ promptAction.showToast({
message: 'tcp client receive error' + JSON.stringify(e), message: 'tcp client receive error' + JSON.stringify(e),
duration: 3000 duration: 3000,
}); });
console.log(TAG, errMsg) console.log(TAG, errMsg);
tcpClient.close() if (timeoutHandle) clearTimeout(timeoutHandle); // 清除超时
tcpClient.close();
resolve({ resolve({
code: -1, message: errMsg code: 2300028,
}) message: errMsg,
}) });
});
}) // 使用 Promise.race 处理超时和 TCP 请求
Promise.race([timeoutPromise, new Promise<RES>((resolveMain) => {
// 将 resolve 逻辑移到此处
tcpClient.on('message', (data) => {
const res = handReceiveMessage(tcpClient, sendData, data.message);
if (res) {
resolveMain(res);
}
});
tcpClient.on('error', (e) => {
const errMsg = 'tcp client receive error' + JSON.stringify(e);
resolveMain({
code: 2300028,
message: errMsg,
});
});
})])
.then((result) => {
if (timeoutHandle) clearTimeout(timeoutHandle); // 清除超时
tcpClient.close();
resolve(result);
})
.catch((error) => {
if (timeoutHandle) clearTimeout(timeoutHandle); // 清除超时
tcpClient.close();
reject(error);
});
});
} }
//处理发送的数据 //处理发送的数据
@ -89,22 +145,23 @@ function handSendMessage(client: socket.TCPSocket, type, data) {
case '02-21-000009': case '02-21-000009':
case '02-21-000012': case '02-21-000012':
case '02-21-000014': case '02-21-000014':
data.forEach((item) => { data.forEach((item, index) => {
client.send({ data: new Uint8Array(item).buffer }) console.log(TAG, "分包", index.toString(), JSON.stringify(item))
client.send({ data: new Uint8Array(item).buffer })
}) })
break; break;
case '02-21-000010': case '02-21-000010':
case '02-21-000011': case '02-21-000011':
case '02-21-000013': case '02-21-000013':
client.send({ data: new Uint8Array(data).buffer }) client.send({ data: new Uint8Array(data).buffer })
break;
default:
break; break;
default:break;
} }
} }
//处理接收的数据 //处理接收的数据
function handReceiveMessage(client: socket.TCPSocket, sendData, rData:ArrayBuffer):RES { function handReceiveMessage(client: socket.TCPSocket, sendData, rData: ArrayBuffer): RES {
const receiveData = new Uint8Array(rData) const receiveData = new Uint8Array(rData)
console.info(TAG, 'receiveData=>' + JSON.stringify(receiveData)) console.info(TAG, 'receiveData=>' + JSON.stringify(receiveData))
//返回的消息类型 //返回的消息类型
@ -112,35 +169,43 @@ function handReceiveMessage(client: socket.TCPSocket, sendData, rData:ArrayBuffe
console.info(TAG, 'receiveData messageType=>' + JSON.stringify(receiveData)) console.info(TAG, 'receiveData messageType=>' + JSON.stringify(receiveData))
//流水号 //流水号
const lsh = bytesToDecimal([receiveData[2],receiveData[3]]); const lsh = bytesToDecimal([receiveData[2], receiveData[3]]);
//开始补包 //开始补包
if(messageType === 0xF0){ if (messageType === 0xF0) {
//获取消息体长度 //获取消息体长度
const messageLength = receiveData[13] const messageLength = receiveData[13]
//分包总数 //分包总数
const packages = receiveData.slice(14, 14 + messageLength * 2); const packages = receiveData.slice(14, 14 + messageLength * 2);
const forArr = new Array(messageLength).fill(1) const forArr = new Array(messageLength).fill(1)
forArr.forEach((item,index)=>{ forArr.forEach((item, index) => {
const start = index * 2; const start = index * 2;
const end = start + 1; const end = start + 1;
const packageIndex = bytesToDecimal([packages[start],packages[end]]); const packageIndex = bytesToDecimal([packages[start], packages[end]]);
console.info(TAG, '补包内容' + JSON.stringify(new Uint8Array(sendData[packageIndex -1]))) console.info(TAG, '补包内容' + JSON.stringify(new Uint8Array(sendData[packageIndex -1])))
client.send({data:new Uint8Array(sendData[packageIndex -1]).buffer}); printInBatches(new Uint8Array(sendData[packageIndex -1]), 100)
client.send({ data: new Uint8Array(sendData[packageIndex -1]).buffer });
}) })
}else{ } else {
const decoder = util.TextDecoder.create('utf-8'); const decoder = util.TextDecoder.create('utf-8');
const messageLength = bytesToDecimal([receiveData[9],receiveData[10]]); const messageLength = bytesToDecimal([receiveData[9], receiveData[10]]);
const markLength = receiveData[11]; const markLength = receiveData[11];
const markContent = decoder.decodeWithStream(receiveData.slice(12, 12 + markLength )); const markContent = decoder.decodeWithStream(receiveData.slice(12, 12 + markLength));
console.info(TAG + messageType, 'markContent=>' + markContent) console.info(TAG + messageType, 'markContent=>' + markContent)
const tipLength = receiveData[13]; const tipLength = receiveData[13];
const messageContent = decoder.decodeWithStream(receiveData.slice(13 + markLength, 13 + markLength + tipLength)); const messageContent = decoder.decodeWithStream(receiveData.slice(13 + markLength, 13 + markLength + tipLength));
console.info(TAG + messageType, 'messageContent=>' + messageContent) console.info(TAG + messageType, 'messageContent=>' + messageContent)
return { return {
code:markContent, code: markContent,
message:messageContent message: messageContent
} }
} }
}
function printInBatches(array, batchSize) {
for (let i = 0; i < array.length; i += batchSize) {
const batch = array.slice(i, i + batchSize);
console.log(TAG, "补包细分", batch);
}
} }