From 5873127e4249693d11d9c321599011ea6b12ba1f Mon Sep 17 00:00:00 2001
From: hxb <hxb@hdlchina.com.cn>
Date: 星期一, 18 九月 2023 19:23:49 +0800
Subject: [PATCH] 处理接收数据优化
---
HDLSDK/com.hdl.sdk/build.gradle | 4
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java | 271 +++++++++++++++++++++++++++++++++-----------
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java | 37 ++++++
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java | 2
4 files changed, 243 insertions(+), 71 deletions(-)
diff --git a/HDLSDK/com.hdl.sdk/build.gradle b/HDLSDK/com.hdl.sdk/build.gradle
index ec71b05..e21c3e9 100644
--- a/HDLSDK/com.hdl.sdk/build.gradle
+++ b/HDLSDK/com.hdl.sdk/build.gradle
@@ -8,8 +8,8 @@
defaultConfig {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
- versionCode 115
- versionName "1.1.5"
+ versionCode 116
+ versionName "1.1.6"
}
buildTypes {
debug {
diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java
index a60b0d7..b0f006f 100644
--- a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java
+++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/common/HDLSdk.java
@@ -35,7 +35,7 @@
return version;
}
- private String version = "1.1.5";
+ private String version = "1.1.6";
private HDLSdk() {
}
diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
index e0f1a43..243d81e 100644
--- a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
+++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
@@ -25,8 +25,11 @@
import com.hdl.sdk.connect.socket.HDLAuthSocket;
import com.hdl.sdk.connect.socket.HDLSocket;
import com.hdl.sdk.connect.utils.AesUtil;
+import com.hdl.sdk.connect.utils.ByteBufferUtils;
import com.hdl.sdk.socket.codec.ByteToMessageDecoder;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -40,13 +43,31 @@
*/
public class LinkMessageDecoder extends ByteToMessageDecoder<LinkResponse> {
- private final List<Byte> bytes;
+ private static final String TAG = LinkMessageDecoder.class.getName();
+ //instance
+ private volatile static LinkMessageDecoder instance;
+
+ //getInstance
+ public static synchronized LinkMessageDecoder getInstance() {
+ if (instance == null) {
+ synchronized (LinkMessageDecoder.class) {
+ if (instance == null) {
+ instance = new LinkMessageDecoder();
+ }
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * 鎺ユ敹鏁版嵁缂撳啿鍖�
+ */
+ private final ByteBuffer byteBuffer;
private final byte[] head = "Topic:".getBytes();
-// private final byte[] body = "\r\n\r\n".getBytes();
public LinkMessageDecoder() {
- this.bytes = new ArrayList<>();
+ byteBuffer = ByteBuffer.allocate(1024 * 200);//100K
}
/// <summary>
@@ -55,11 +76,16 @@
/// <param name="topMsgs"></param>
/// <returns></returns>
int getLenght(String[] topMsgs) {
- for (int i = 0; i < topMsgs.length; i++) {
- String topMsg = topMsgs[i].trim();
- if (topMsg.startsWith("Length:")) {
- return Integer.parseInt(topMsg.replace("Length:", ""));
+ try {
+ for (int i = 0; i < topMsgs.length; i++) {
+ String topMsg = topMsgs[i].trim();
+ if (topMsg.startsWith("Length:")) {
+ return Integer.parseInt(topMsg.replace("Length:", "").trim());
+ }
}
+ } catch (Exception e) {
+ LogUtils.e("寮傚父鏁版嵁锛�" + topMsgs[0] + "\r\n" + topMsgs[1]);
+ return -1;
}
//鎵句笉鍒伴暱搴�
return -1;
@@ -84,15 +110,14 @@
/**
* 鑾峰彇鏁版嵁鐨勫紑濮嬩綅缃�
*
- * @param arrayList 鎺ユ敹鍒扮殑鎵�鏈夋暟鎹�
* @return 鏁版嵁浣嶇殑寮�濮嬬储寮�
*/
- int getDataIndex(List<Byte> arrayList) {
+ int getBodyIndex() {
byte r = (byte) '\r';
byte n = (byte) '\n';
- for (int i = 0; i < arrayList.size(); i++) {
+ for (int i = 0; i < byteBuffer.position(); i++) {
//鎵惧嚭鏁版嵁鍐呭鍓嶉潰鐨勪袱涓崲琛�
- if (3 <= i && arrayList.get(i - 3) == r && arrayList.get(i - 2) == n && arrayList.get(i - 1) == r && arrayList.get(i) == n) {
+ if (3 <= i && byteBuffer.get(i - 3) == r && byteBuffer.get(i - 2) == n && byteBuffer.get(i - 1) == r && byteBuffer.get(i) == n) {
//鍓╀綑鐨勬暟鎹�
return i + 1;
}
@@ -100,14 +125,73 @@
return -1;
}
- void initReceiveData(List<Byte> list) {
+ /**
+ * 鑾峰彇澶撮儴鏁版嵁
+ *
+ * @return
+ */
+ String getHeader() {
+ int bodyIndex = getBodyIndex();
+ if (bodyIndex < 0) {
+ //娌℃湁鎵惧埌澶撮儴鏁版嵁
+ return null;
+ } else {
+ byte bodyBytes[] = ByteBufferUtils.copyBytes(byteBuffer, bodyIndex);
+ return new String(bodyBytes);
+ }
+ }
+ /**
+ * 鑾峰彇鏁版嵁鍐呭
+ *
+ * @param lenght
+ * @return
+ */
+ byte[] getBody(int index, int lenght) {
+ //鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
+ byte[] bodyBytes = new byte[lenght];
+ if (index < 0 || byteBuffer.position() < index + lenght) {
+ //褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+ return null;
+ }
+
+ for (int i = 0; i < bodyBytes.length; i++) {
+ bodyBytes[i] = byteBuffer.get(index + i);
+ }
+ return bodyBytes;
+ }
+
+
+ /**
+ * 杩欒竟澶勭悊浜嗙紦瀛樻暟鎹矘鍖呯殑鎯呭喌锛屾瘡娆¤姹傞兘闇�瑕佸惂褰撳墠瀹屾暣鐨勬枃浠堕櫎鍘� 浠ヤ究浜庝笅娆$殑杩斿洖
+ * tempList鐢ㄤ簬瀛樺偍澶氫綑鐨勬暟鎹�
+ * contentList鐢ㄤ簬鏈鏁版嵁鐨勫瓨鍌紙鍙戦�佺粰璁㈤槄鐨勬暟鎹級
+ */
+ byte[] geBody() {
+ int len = 3 + 4 + 4 + ((byteBuffer.get(7) & 0xFF) * 256 * 256 * 256) + ((byteBuffer.get(8) & 0xFF) * 256 * 256) + ((byteBuffer.get(9) * 256) & 0xFF) + (byteBuffer.get(10) & 0xFf);
+ byte[] bodyBytes = new byte[len];
+ for (int i = 0; i < len; i++) {
+ bodyBytes[i] = byteBuffer.get(i);
+ }
+
+ int endIndex = byteBuffer.position();
+ byteBuffer.clear();
+ for (int i = len; i < endIndex; i++) {
+ byteBuffer.put(byteBuffer.get(i));
+ }
+ return bodyBytes;
+ }
+
+ /**
+ * 绉婚櫎鍙兘瀛樺湪鐨勬棤鏁堟暟鎹�
+ */
+ void removeInVoidBytes() {
int index = 0;
boolean isMatch = false;
- for (; index < list.size() - head.length; index++) {
+ for (; index < byteBuffer.position() - head.length; index++) {
isMatch = true;
for (int j = 0, k = 0; j < head.length; j++, k++) {
- if (head[j] != list.get(index + k)) {
+ if (head[j] != byteBuffer.get(index + k)) {
isMatch = false;
break;
}
@@ -118,97 +202,148 @@
}
if (0 < index && isMatch) {
- List<Byte> tempList = new ArrayList<Byte>();
- for (int i = index; i < list.size(); i++) {
- tempList.add(list.get(i));
- }
-
- list.clear();
- for (int i = 0; i < tempList.size(); i++) {
- list.add(tempList.get(i));
+ int endIndex = byteBuffer.position();
+ byteBuffer.clear();
+ for (int i = index; i < endIndex; i++) {
+ byteBuffer.put(byteBuffer.get(i));
}
}
+ }
+
+ /**
+ * 绉婚櫎鍒版寚瀹氫綅缃墠闈㈢殑鏁版嵁
+ *
+ * @param position 鎸囧畾浣嶇疆
+ */
+ void remove(int position) {
+ int endIndex = byteBuffer.position();
+ byteBuffer.clear();
+ for (int i = position; i < endIndex; i++) {
+ byteBuffer.put(byteBuffer.get(i));
+ }
+ }
+
+
+ int bytes2int(byte[] bytes) {
+ int result = 0;
+ if (bytes.length == 2) {
+ int c = (bytes[0] & 0xff) << 8;
+ int d = (bytes[1] & 0xff);
+ result = c | d;
+ } else if (bytes.length == 4) {
+ return bytes[3] & 0xFF | //
+ (bytes[2] & 0xFF) << 8 | //
+ (bytes[1] & 0xFF) << 16 | //
+ (bytes[0] & 0xFF) << 24; //
+ }
+ return result;
+ }
+
+ public String byte2hex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ String tmp = null;
+ for (byte b : bytes) {
+ //灏嗘瘡涓瓧鑺備笌0xFF杩涜涓庤繍绠楋紝鐒跺悗杞寲涓�10杩涘埗锛岀劧鍚庡�熷姪浜嶪nteger鍐嶈浆鍖栦负16杩涘埗
+ tmp = Integer.toHexString(0xFF & b);
+ if (tmp.length() == 1) {
+ tmp = "0" + tmp;
+ }
+ sb.append(tmp + " ");
+ }
+ return sb.toString();
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected synchronized LinkResponse decoder(Object msg, String ipaddress) throws Exception {
- if (msg instanceof byte[]) {
- bytes.addAll(ByteUtils.toByteList((byte[]) msg));
+ if (msg == null || !(msg instanceof byte[])) {
+ return null;
+ }
+
+ byte[] bytes = (byte[]) msg;
+ try {
+ byteBuffer.put(bytes);
+ } catch (Exception e) {
+ LogUtils.e("鎺ユ敹鍒版暟鎹紓甯�:\r\n" + e.getMessage());
+ byteBuffer.flip();
+ byteBuffer.clear();
+ }
+
+ try {
//濡傛灉澶氭潯鍛戒护鎵撳寘鍦ㄤ竴鏉℃暟鎹腑锛岄兘闇�瑕佸鐞嗗畬
while (true) {
- initReceiveData(bytes);
- byte[] recevieBytes = ByteUtils.toByteArray(bytes);
- String data = new String(recevieBytes);
+ removeInVoidBytes();//绉婚櫎鍙兘瀛樺湪鐨勬棤鏁堟暟鎹�
- String[] topMsgs = data.split("\r\n");
+ //澶撮儴鏁版嵁
+ String header = getHeader();
+
+ if (header == null) {
+ break;
+ }
+ String[] topMsgs = header.split("\r\n");
String topic = getTopic(topMsgs);
- if (topic == null) {
- break;
- }
-
int lenght = getLenght(topMsgs);
-
- if (lenght <= 0) {
- //澶撮儴鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+ if (topic == null || lenght <= 0) {
+ //鑾峰彇涓嶅埌涓婚鎴栬�呭ご閮ㄦ暟鎹繕娌℃湁鎺ユ敹瀹屾垚
break;
}
+
+ int bodyIndex = getBodyIndex();
//鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
- byte[] body = new byte[lenght];
- int index = getDataIndex(bytes);
- if (bytes.size() < index + lenght) {
+ byte[] body = getBody(bodyIndex, lenght);
+
+ if (body == null) {
//褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
break;
}
- //澶嶅埗鍑篵ody鏁版嵁
- System.arraycopy(recevieBytes, index, body, 0, body.length);
- //淇濈暀鍓╀綑鐨勬暟鎹紝浠ユ鐢�
- bytes.clear();
- for (int i = index + lenght; i < recevieBytes.length; i++) {
- bytes.add(recevieBytes[i]);
+ remove(bodyIndex + lenght);
+
+ if (topic.contains("heartbeat_reply")) {
+// if (packet.getSocket() != null) {
+// packet.getSocket().setSoTimeout(10 * 1000);
+// }
+ continue;
}
+
LinkResponse response = new LinkResponse();
response.setSource_ipAddress(ipaddress);
- Log.d("panlili", "----->source_ipAddress= " + ipaddress);
response.setTopic(topic);
- if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
+
+ if (encrypt(body)) {
//闇�瑕佽В瀵�
byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
if (bodyBytes != null) {
- body = bodyBytes;
+ response.setData(new String(bodyBytes, StandardCharsets.UTF_8));
} else {
- try {
- //涔嬪墠鐨勭増鏈繖鍧楁槸鏄庢枃鐨�
- if (!topic.contains("heartbeat_reply")) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
- LogUtils.e("瑙e瘑澶辫触锛屾暟鎹唴瀹规槸锛歕r\n" + Base64.encodeToString(body, Base64.NO_WRAP));
- else {
- LogUtils.e("瑙e瘑澶辫触锛屾暟鎹唴瀹规槸锛歕r\n" + new String(body, "utf-8"));
- }
- }
- } catch (Exception e) {
- }
+ LogUtils.e("瑙e瘑澶辫触\r\n" + topic);
+ response.setData(new String(body, "utf-8"));
+ continue;
}
+ } else {
+ response.setData(new String(body, "utf-8"));
}
- String bodyString = new String(body, "utf-8");
- response.setData(bodyString);
- LogUtils.i("鎺ユ敹鍒版暟鎹�:" + response.getTopic() + "\r\n" + response.getData());
+ LogUtils.i("鏈湴鎺ユ敹鍒版暟鎹�:\r\n" + response.getTopic() + "\r\n" + response.getData() + "\r\n" + response.getData().length());
- //闈炴甯告暟鎹紝杩斿洖
- if (!((bodyString.startsWith("{") && bodyString.endsWith("}"))
- || (bodyString.startsWith("[") && bodyString.endsWith("]")))) {
- continue;
- }
//瑙f瀽瀹屾垚,topic鍙戦�佷竴娆�
EventDispatcher.getInstance().post(response.getTopic(), response);
}
- return null;
-
+ } catch (Exception ee) {
+ LogUtils.e("澶勭悊鎺ユ敹鐨勬暟鎹紓甯�:\r\n" + ee.getMessage());
}
return null;
}
+
+ //鏄惁鍔犲瘑
+ private boolean encrypt(byte[] bytes) {
+ if (bytes[0] == '{' && bytes[bytes.length - 1] == '}' || (bytes[0] == '[' && bytes[bytes.length - 1] == ']')) {
+ return false;
+ }
+ return true;
+ }
}
+
+
diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java
new file mode 100644
index 0000000..032c9d3
--- /dev/null
+++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ByteBufferUtils.java
@@ -0,0 +1,37 @@
+package com.hdl.sdk.connect.utils;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Created by hxb on 2022/8/3.
+ *
+ */
+public class ByteBufferUtils {
+
+ /**
+ * 鑾峰彇ByteBuffer鎸囧畾浣嶇疆鏁版嵁
+ *
+ * @param byteBuffer 婧愬璞�
+ * @param length 鎸囧畾闀垮害
+ * @return 鏍规嵁闀垮害鐢熸垚鐨勬暟缁�
+ */
+ public static byte[] copyBytes(ByteBuffer byteBuffer, int length) {
+ return copyBytes(byteBuffer,0,length);
+ }
+
+ /**
+ * 澶嶅埗鎸囧畾浣嶇疆鐨勬暟鎹�
+ * @param byteBuffer
+ * @param index
+ * @param length
+ * @return
+ */
+ public static byte[] copyBytes(ByteBuffer byteBuffer, int index,int length) {
+ byte[] bytes = new byte[length];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = byteBuffer.get(index + i);
+ }
+ return bytes;
+ }
+
+}
--
Gitblit v1.8.0