diff --git a/plugins/sonic-android-apk.apk b/plugins/sonic-android-apk.apk
index 58999bc2..ff7233ea 100644
Binary files a/plugins/sonic-android-apk.apk and b/plugins/sonic-android-apk.apk differ
diff --git a/pom.xml b/pom.xml
index 1aeeff10..668f4bf3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.cloud.sonic
sonic-agent
- 1.3.1-beta
+ 1.3.1-release
jar
diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java
index 6979fc6e..98f45598 100644
--- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java
@@ -533,7 +533,7 @@ public void install(HandleDes handleDes, String path) {
try {
androidDriver.installApp(path, new AndroidInstallApplicationOptions()
.withAllowTestPackagesEnabled().withReplaceEnabled()
- .withGrantPermissionsEnabled().withTimeout(Duration.ofMillis(60000)));
+ .withGrantPermissionsEnabled().withTimeout(Duration.ofMillis(600000)));
} catch (Exception e) {
handleDes.setE(e);
return;
@@ -822,7 +822,7 @@ public void tap(HandleDes handleDes, String des, String xy) {
}
}
- public void swipe(HandleDes handleDes, String des1, String xy1, String des2, String xy2) {
+ public void swipePoint(HandleDes handleDes, String des1, String xy1, String des2, String xy2) {
int x1 = Integer.parseInt(xy1.substring(0, xy1.indexOf(",")));
int y1 = Integer.parseInt(xy1.substring(xy1.indexOf(",") + 1));
int x2 = Integer.parseInt(xy2.substring(0, xy2.indexOf(",")));
@@ -837,6 +837,23 @@ public void swipe(HandleDes handleDes, String des1, String xy1, String des2, Str
}
}
+ public void swipe(HandleDes handleDes, String des, String selector, String pathValue, String des2, String selector2, String pathValue2) {
+ WebElement webElement = findEle(selector, pathValue);
+ WebElement webElement2 = findEle(selector2, pathValue2);
+ int x1 = webElement.getLocation().getX();
+ int y1 = webElement.getLocation().getY();
+ int x2 = webElement2.getLocation().getX();
+ int y2 = webElement2.getLocation().getY();
+ handleDes.setStepDes("滑动拖拽" + des + "到" + des2);
+ handleDes.setDetail("拖动坐标(" + x1 + "," + y1 + ")到(" + x2 + "," + y2 + ")");
+ try {
+ TouchAction ta = new TouchAction(androidDriver);
+ ta.press(PointOption.point(x1, y1)).waitAction(WaitOptions.waitOptions(Duration.ofMillis(300))).moveTo(PointOption.point(x2, y2)).release().perform();
+ } catch (Exception e) {
+ handleDes.setE(e);
+ }
+ }
+
public void longPress(HandleDes handleDes, String des, String selector, String pathValue, int time) {
handleDes.setStepDes("长按" + des);
handleDes.setDetail("长按控件元素" + time + "毫秒 ");
@@ -1440,9 +1457,13 @@ public void runStep(JSONObject stepJSON) throws Throwable {
, eleList.getJSONObject(0).getString("eleValue"), Integer.parseInt(step.getString("content")));
break;
case "swipe":
- swipe(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue")
+ swipePoint(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue")
, eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleValue"));
break;
+ case "swipe2":
+ swipe(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue")
+ , eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleType"), eleList.getJSONObject(1).getString("eleValue"));
+ break;
case "tap":
tap(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue"));
break;
diff --git a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java
index 5851752f..9cf71231 100644
--- a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java
@@ -107,7 +107,7 @@ public void startIOSDriver(String udId, int wdaPort) throws InterruptedException
iosDriver.setSetting(Setting.MJPEG_SERVER_FRAMERATE, 50);
iosDriver.setSetting(Setting.MJPEG_SCALING_FACTOR, 50);
iosDriver.setSetting(Setting.MJPEG_SERVER_SCREENSHOT_QUALITY, 10);
- iosDriver.setSetting("snapshotMaxDepth",30);
+ iosDriver.setSetting("snapshotMaxDepth", 30);
log.sendStepLog(StepType.PASS, "连接设备驱动成功", "");
} catch (Exception e) {
log.sendStepLog(StepType.ERROR, "连接设备驱动失败!", "");
@@ -517,7 +517,7 @@ public void tap(HandleDes handleDes, String des, String xy) {
}
}
- public void swipe(HandleDes handleDes, String des1, String xy1, String des2, String xy2) {
+ public void swipePoint(HandleDes handleDes, String des1, String xy1, String des2, String xy2) {
int x1 = Integer.parseInt(xy1.substring(0, xy1.indexOf(",")));
int y1 = Integer.parseInt(xy1.substring(xy1.indexOf(",") + 1));
int x2 = Integer.parseInt(xy2.substring(0, xy2.indexOf(",")));
@@ -532,6 +532,23 @@ public void swipe(HandleDes handleDes, String des1, String xy1, String des2, Str
}
}
+ public void swipe(HandleDes handleDes, String des, String selector, String pathValue, String des2, String selector2, String pathValue2) {
+ WebElement webElement = findEle(selector, pathValue);
+ WebElement webElement2 = findEle(selector2, pathValue2);
+ int x1 = webElement.getLocation().getX();
+ int y1 = webElement.getLocation().getY();
+ int x2 = webElement2.getLocation().getX();
+ int y2 = webElement2.getLocation().getY();
+ handleDes.setStepDes("滑动拖拽" + des + "到" + des2);
+ handleDes.setDetail("拖动坐标(" + x1 + "," + y1 + ")到(" + x2 + "," + y2 + ")");
+ try {
+ TouchAction ta = new TouchAction(iosDriver);
+ ta.press(PointOption.point(x1, y1)).waitAction(WaitOptions.waitOptions(Duration.ofMillis(300))).moveTo(PointOption.point(x2, y2)).release().perform();
+ } catch (Exception e) {
+ handleDes.setE(e);
+ }
+ }
+
public void longPress(HandleDes handleDes, String des, String selector, String pathValue, int time) {
handleDes.setStepDes("长按" + des);
handleDes.setDetail("长按控件元素" + time + "毫秒 ");
@@ -830,9 +847,13 @@ public void runStep(JSONObject stepJSON) throws Throwable {
, eleList.getJSONObject(0).getString("eleValue"), Integer.parseInt(step.getString("content")));
break;
case "swipe":
- swipe(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue")
+ swipePoint(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue")
, eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleValue"));
break;
+ case "swipe2":
+ swipe(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue")
+ , eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleType"), eleList.getJSONObject(1).getString("eleValue"));
+ break;
case "tap":
tap(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue"));
break;
diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
index ebd68a2d..d55b27da 100644
--- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
+++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
@@ -12,9 +12,14 @@
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
@@ -133,7 +138,7 @@ public static void reboot(IDevice iDevice) {
public static IDevice getIDeviceByUdId(String udId) {
IDevice iDevice = null;
IDevice[] iDevices = AndroidDeviceBridgeTool.getRealOnLineDevices();
- if(iDevices.length==0){
+ if (iDevices.length == 0) {
return null;
}
for (IDevice device : iDevices) {
@@ -202,6 +207,15 @@ public static String executeCommand(IDevice iDevice, String command) {
return output.getOutput();
}
+ public static boolean checkSonicApkVersion(IDevice iDevice) {
+ String all = executeCommand(iDevice, "dumpsys package org.cloud.sonic.android");
+ if (!all.contains("versionName=1.3.2")) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
/**
* @param iDevice
* @param port
diff --git a/src/main/java/org/cloud/sonic/agent/tests/android/SonicLocalThread.java b/src/main/java/org/cloud/sonic/agent/tests/android/SonicLocalThread.java
index fa24a856..00f63c7d 100644
--- a/src/main/java/org/cloud/sonic/agent/tests/android/SonicLocalThread.java
+++ b/src/main/java/org/cloud/sonic/agent/tests/android/SonicLocalThread.java
@@ -162,7 +162,7 @@ public void run() {
if (man == null) {
return;
}
- if (!suc && iDevice != null && man.equals("Xiaomi")) {
+ if (!suc && iDevice != null && (man.equals("Xiaomi") || man.equals("deltainno") || man.equals("HUAWEI"))) {
suc = runMiniCap("Xiaomi");
if (!suc && iDevice != null) {
suc = runMiniCap("Xiaomi_NW");
diff --git a/src/main/java/org/cloud/sonic/agent/tools/AgentTool.java b/src/main/java/org/cloud/sonic/agent/tools/AgentTool.java
index 2df2e085..d890f2d2 100644
--- a/src/main/java/org/cloud/sonic/agent/tools/AgentTool.java
+++ b/src/main/java/org/cloud/sonic/agent/tools/AgentTool.java
@@ -52,6 +52,19 @@ public static void sendByte(Session session, byte[] message) {
}
}
+ public static void sendByte(Session session, ByteBuffer message) {
+ if (session == null || !session.isOpen()) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ session.getBasicRemote().sendBinary(message);
+ } catch (IllegalStateException | IOException e) {
+ log.error("WebSocket发送失败!连接已关闭!");
+ }
+ }
+ }
+
public static void sendText(Session session, String message) {
if (session == null || !session.isOpen()) {
return;
diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java
index adbd031c..89e4ab41 100644
--- a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java
+++ b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java
@@ -96,13 +96,15 @@ public void onOpen(Session session, @PathParam("key") String secretKey,
.replaceAll("package:", "")
.replaceAll("\n", "")
.replaceAll("\t", "");
- if (path.length() > 0) {
- logger.info("已安装Sonic插件");
+ if (path.length() > 0 && AndroidDeviceBridgeTool.checkSonicApkVersion(iDevice)) {
+ logger.info("已安装Sonic插件,检查版本信息通过");
} else {
+ logger.info("未安装Sonic插件或版本不是最新,正在安装...");
try {
iDevice.installPackage("plugins/sonic-android-apk.apk",
true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES
, "-r", "-t", "-g");
+ logger.info("Sonic插件安装完毕");
} catch (InstallException e) {
e.printStackTrace();
logger.info("Sonic插件安装失败!");
diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AudioWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AudioWSServer.java
index e6e1cdef..3ba32e03 100644
--- a/src/main/java/org/cloud/sonic/agent/websockets/AudioWSServer.java
+++ b/src/main/java/org/cloud/sonic/agent/websockets/AudioWSServer.java
@@ -1,34 +1,69 @@
package org.cloud.sonic.agent.websockets;
+import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.android.ddmlib.IDevice;
import org.cloud.sonic.agent.bridge.android.AndroidDeviceBridgeTool;
-import org.cloud.sonic.agent.bridge.android.AndroidDeviceThreadPool;
+import org.cloud.sonic.agent.maps.AndroidAPKMap;
import org.cloud.sonic.agent.tools.AgentTool;
import org.cloud.sonic.agent.tools.PortTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
-import javax.websocket.OnOpen;
-import javax.websocket.Session;
+import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
-import java.util.concurrent.Future;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
@Component
-@ServerEndpoint(value = "/websockets/audio/{udId}", configurator = MyEndpointConfigure.class)
+@ServerEndpoint(value = "/websockets/audio/{key}/{udId}", configurator = MyEndpointConfigure.class)
public class AudioWSServer {
+ private final Logger logger = LoggerFactory.getLogger(AudioWSServer.class);
+ @Value("${sonic.agent.key}")
+ private String key;
+ private Map udIdMap = new ConcurrentHashMap<>();
+ private Map audioMap = new ConcurrentHashMap<>();
+
@OnOpen
- public void onOpen(Session session,@PathParam("udId") String udId) throws Exception {
+ public void onOpen(Session session, @PathParam("key") String secretKey, @PathParam("udId") String udId) throws Exception {
+ if (secretKey.length() == 0 || (!secretKey.equals(key))) {
+ logger.info("拦截访问!");
+ return;
+ }
IDevice iDevice = AndroidDeviceBridgeTool.getIDeviceByUdId(udId);
+ udIdMap.put(session, iDevice);
+ int wait = 0;
+ boolean isInstall = true;
+ while (AndroidAPKMap.getMap().get(udId) == null || (!AndroidAPKMap.getMap().get(udId))) {
+ Thread.sleep(500);
+ wait++;
+ if (wait >= 40) {
+ isInstall = false;
+ break;
+ }
+ }
+ if (!isInstall) {
+ logger.info("等待安装超时!");
+ } else {
+ startAudio(session);
+ }
+ }
+
+ private void startAudio(Session session) {
+ stopAudio(session);
+ IDevice iDevice = udIdMap.get(session);
AndroidDeviceBridgeTool.executeCommand(iDevice, "appops set org.cloud.sonic.android PROJECT_MEDIA allow");
AndroidDeviceBridgeTool.executeCommand(iDevice, "am start -n org.cloud.sonic.android/.AudioActivity");
AndroidDeviceBridgeTool.pressKey(iDevice, 4);
int appListPort = PortTool.getPort();
- new Thread(()-> {
+ Thread audio = new Thread(() -> {
try {
AndroidDeviceBridgeTool.forward(iDevice, appListPort, "sonicaudioservice");
Socket audioSocket = null;
@@ -37,7 +72,7 @@ public void onOpen(Session session,@PathParam("udId") String udId) throws Except
audioSocket = new Socket("localhost", appListPort);
inputStream = audioSocket.getInputStream();
int len = 1024;
- while (audioSocket.isConnected()) {
+ while (audioSocket.isConnected() && !Thread.interrupted()) {
byte[] buffer = new byte[len];
int realLen;
realLen = inputStream.read(buffer);
@@ -49,7 +84,7 @@ public void onOpen(Session session,@PathParam("udId") String udId) throws Except
byteBuffer.put(buffer);
byteBuffer.flip();
//bug
- sendText(session, byteBuffer);
+ AgentTool.sendByte(session, byteBuffer);
}
}
} catch (IOException e) {
@@ -73,15 +108,62 @@ public void onOpen(Session session,@PathParam("udId") String udId) throws Except
} catch (Exception e) {
}
AndroidDeviceBridgeTool.removeForward(iDevice, appListPort, "sonicaudioservice");
- }).start();
+ });
+ audio.start();
+ audioMap.put(session, audio);
}
- private void sendText(Session session, ByteBuffer message) {
- synchronized (session) {
- try {
- session.getBasicRemote().sendBinary(message);
- } catch (IllegalStateException | IOException e) {
+ private void stopAudio(Session session) {
+ if (audioMap.get(session) != null) {
+ audioMap.get(session).interrupt();
+ int wait = 0;
+ while (!audioMap.get(session).isInterrupted()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ wait++;
+ if (wait >= 3) {
+ break;
+ }
}
}
+ audioMap.remove(session);
+ }
+
+// @OnMessage
+// public void onMessage(String message, Session session) {
+// JSONObject msg = JSON.parseObject(message);
+// logger.info(session.getId() + " 发送 " + msg);
+// switch (msg.getString("type")) {
+// case "start":
+// startAudio(session);
+// break;
+// case "stop":
+// stopAudio(session);
+// break;
+// }
+// }
+
+ @OnClose
+ public void onClose(Session session) {
+ exit(session);
+ }
+
+ @OnError
+ public void onError(Session session, Throwable error) {
+ logger.error("音频socket发生错误,刷新瞬间可无视:", error);
+ }
+
+ private void exit(Session session) {
+ stopAudio(session);
+ udIdMap.remove(session);
+ try {
+ session.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ logger.info(session.getId() + "退出");
}
}
diff --git a/src/main/java/org/cloud/sonic/agent/websockets/TerminalWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/TerminalWSServer.java
index f281a663..5fa086aa 100644
--- a/src/main/java/org/cloud/sonic/agent/websockets/TerminalWSServer.java
+++ b/src/main/java/org/cloud/sonic/agent/websockets/TerminalWSServer.java
@@ -2,7 +2,8 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
-import com.android.ddmlib.*;
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.IShellOutputReceiver;
import org.cloud.sonic.agent.bridge.android.AndroidDeviceBridgeTool;
import org.cloud.sonic.agent.bridge.android.AndroidDeviceThreadPool;
import org.cloud.sonic.agent.maps.AndroidAPKMap;
@@ -32,6 +33,7 @@
@Component
@ServerEndpoint(value = "/websockets/terminal/{key}/{udId}", configurator = MyEndpointConfigure.class)
public class TerminalWSServer {
+
private final Logger logger = LoggerFactory.getLogger(TerminalWSServer.class);
@Value("${sonic.agent.key}")
private String key;
@@ -39,7 +41,6 @@ public class TerminalWSServer {
private Map> terminalMap = new ConcurrentHashMap<>();
private Map> appListMap = new ConcurrentHashMap<>();
private Map> logcatMap = new ConcurrentHashMap<>();
- private Map> audioMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("key") String secretKey, @PathParam("udId") String udId) throws Exception {
@@ -214,15 +215,6 @@ private void exit(Session session) {
}
}
terminalMap.remove(session);
- Future> audioPro = audioMap.get(session);
- if (audioPro != null && (!audioPro.isDone() || !audioPro.isCancelled())) {
- try {
- audioPro.cancel(true);
- } catch (Exception e) {
- logger.error(e.getMessage());
- }
- }
- audioMap.remove(session);
Future> logcat = logcatMap.get(session);
if (!logcat.isDone() || !logcat.isCancelled()) {
try {
@@ -232,6 +224,7 @@ private void exit(Session session) {
}
}
logcatMap.remove(session);
+ udIdMap.remove(session);
try {
session.close();
} catch (IOException e) {
@@ -250,69 +243,6 @@ private void sendText(Session session, String message) {
}
}
-// public void getAudio(IDevice iDevice, Session session) {
-// Future> audioPro = audioMap.get(session);
-// if (audioPro != null && (!audioPro.isDone() || !audioPro.isCancelled())) {
-// try {
-// audioPro.cancel(true);
-// } catch (Exception e) {
-// logger.error(e.getMessage());
-// }
-// }
-// audioPro = AndroidDeviceThreadPool.cachedThreadPool.submit(() -> {
-// AndroidDeviceBridgeTool.executeCommand(iDevice, "appops set org.cloud.sonic.android PROJECT_MEDIA allow");
-// AndroidDeviceBridgeTool.executeCommand(iDevice, "am start -n org.cloud.sonic.android/.AudioActivity");
-// AndroidDeviceBridgeTool.pressKey(iDevice, 4);
-// int appListPort = PortTool.getPort();
-// try {
-// AndroidDeviceBridgeTool.forward(iDevice, appListPort, "sonicaudioservice");
-// Socket audioSocket = null;
-// InputStream inputStream = null;
-// try {
-// audioSocket = new Socket("localhost", appListPort);
-// inputStream = audioSocket.getInputStream();
-// int len = 1024;
-// while (audioSocket.isConnected() && !Thread.interrupted()) {
-// byte[] buffer = new byte[len];
-// int realLen;
-// realLen = inputStream.read(buffer);
-// if (buffer.length != realLen && realLen >= 0) {
-// buffer = AgentTool.subByteArray(buffer, 0, realLen);
-// }
-// if (realLen >= 0) {
-//// System.out.println(buffer);
-// }
-// }
-// } catch (IOException e) {
-// e.printStackTrace();
-// } finally {
-// if (audioSocket != null && audioSocket.isConnected()) {
-// try {
-// audioSocket.close();
-// logger.info("audio socket已关闭");
-// } catch (IOException e) {
-// e.printStackTrace();
-// }
-// }
-// if (inputStream != null) {
-// try {
-// inputStream.close();
-// logger.info("audio output流已关闭");
-// } catch (IOException e) {
-// e.printStackTrace();
-// }
-// }
-// }
-// } catch (Exception e) {
-// logger.info("{} 设备远程音频服务启动异常!"
-// , iDevice.getSerialNumber());
-// logger.error(e.getMessage());
-// }
-// AndroidDeviceBridgeTool.removeForward(iDevice, appListPort, "sonicaudioservice");
-// });
-// audioMap.put(session, audioPro);
-// }
-
public void getAppList(IDevice iDevice, Session session) {
Future> app = appListMap.get(session);
if (app != null && (!app.isDone() || !app.isCancelled())) {
@@ -333,26 +263,28 @@ public void getAppList(IDevice iDevice, Session session) {
try {
appListSocket = new Socket("localhost", appListPort);
inputStream = appListSocket.getInputStream();
- int len = 1024;
- String total = "";
while (appListSocket.isConnected()) {
- byte[] buffer = new byte[len];
- int realLen;
- realLen = inputStream.read(buffer);
- if (buffer.length != realLen && realLen >= 0) {
- buffer = AgentTool.subByteArray(buffer, 0, realLen);
+ // 获取长度
+ byte[] lengthBytes = inputStream.readNBytes(32);
+ if (Thread.interrupted() || lengthBytes.length == 0) {
+ // lengthBytes.length基本就是中断的时候强制唤醒导致的
+ break;
}
- if (realLen >= 0) {
- String chunk = new String(buffer);
- total += chunk;
- if (chunk.contains("}")) {
- JSONObject appListDetail = new JSONObject();
- appListDetail.put("msg", "appListDetail");
- appListDetail.put("detail", JSON.parseObject(total));
- AgentTool.sendText(session, appListDetail.toJSONString());
- total = "";
- }
+ // byte转字符串(二进制),然后再转长度
+ StringBuffer binStr = new StringBuffer();
+ for (byte lengthByte : lengthBytes) {
+ binStr.append(lengthByte);
}
+ Integer readLen = Integer.valueOf(binStr.toString(), 2);
+
+ // 根据长度读取数据体
+ byte[] dataBytes = inputStream.readNBytes(readLen);
+ String dataJson = new String(dataBytes);
+
+ JSONObject appListDetail = new JSONObject();
+ appListDetail.put("msg", "appListDetail");
+ appListDetail.put("detail", JSON.parseObject(dataJson));
+ AgentTool.sendText(session, appListDetail.toJSONString());
}
} catch (IOException e) {
e.printStackTrace();