Move terminal writes off main thread
This commit is contained in:
parent
72913c5571
commit
7b13d42930
@ -12,6 +12,9 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
|
||||||
@ -25,6 +28,8 @@ final class TerminalSocketClient {
|
|||||||
|
|
||||||
private final Object writeLock = new Object();
|
private final Object writeLock = new Object();
|
||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
|
private final ExecutorService writeExecutor = Executors.newSingleThreadExecutor(runnable ->
|
||||||
|
new Thread(runnable, "terminal-ws-write"));
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private BufferedInputStream input;
|
private BufferedInputStream input;
|
||||||
private BufferedOutputStream output;
|
private BufferedOutputStream output;
|
||||||
@ -42,32 +47,34 @@ final class TerminalSocketClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendInput(String data) {
|
void sendInput(String data) {
|
||||||
sendMessage("input", "data", data);
|
sendMessageAsync("input", "data", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int cols, int rows) {
|
void resize(int cols, int rows) {
|
||||||
sendMessage("resize", "cols", cols, "rows", rows);
|
sendMessageAsync("resize", "cols", cols, "rows", rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll(int lines) {
|
void scroll(int lines) {
|
||||||
sendMessage("scroll", "lines", lines);
|
sendMessageAsync("scroll", "lines", lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearHistory() {
|
void clearHistory() {
|
||||||
sendMessage("clear-history");
|
sendMessageAsync("clear-history");
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
closed = true;
|
closed = true;
|
||||||
|
try {
|
||||||
|
writeExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
sendFrame(8, new byte[0]);
|
sendFrame(8, new byte[0]);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
try {
|
closeSocketQuietly();
|
||||||
if (socket != null) {
|
});
|
||||||
socket.close();
|
writeExecutor.shutdown();
|
||||||
}
|
} catch (RejectedExecutionException ignored) {
|
||||||
} catch (Exception ignored) {
|
closeSocketQuietly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +89,7 @@ final class TerminalSocketClient {
|
|||||||
input = new BufferedInputStream(socket.getInputStream());
|
input = new BufferedInputStream(socket.getInputStream());
|
||||||
output = new BufferedOutputStream(socket.getOutputStream());
|
output = new BufferedOutputStream(socket.getOutputStream());
|
||||||
handshake(uri);
|
handshake(uri);
|
||||||
sendMessage(
|
sendMessageSync(
|
||||||
"attach",
|
"attach",
|
||||||
"tabId", "android-" + System.currentTimeMillis(),
|
"tabId", "android-" + System.currentTimeMillis(),
|
||||||
"sessionName", sessionName,
|
"sessionName", sessionName,
|
||||||
@ -98,12 +105,8 @@ final class TerminalSocketClient {
|
|||||||
} finally {
|
} finally {
|
||||||
closed = true;
|
closed = true;
|
||||||
listener.onClosed();
|
listener.onClosed();
|
||||||
try {
|
closeSocketQuietly();
|
||||||
if (socket != null) {
|
writeExecutor.shutdownNow();
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +246,7 @@ final class TerminalSocketClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendJson(JSONObject object) {
|
private void sendJsonSync(JSONObject object) {
|
||||||
try {
|
try {
|
||||||
sendFrame(1, object.toString().getBytes(StandardCharsets.UTF_8));
|
sendFrame(1, object.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
} catch (Exception error) {
|
} catch (Exception error) {
|
||||||
@ -253,14 +256,21 @@ final class TerminalSocketClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(String type, Object... keyValues) {
|
private void sendMessageAsync(String type, Object... keyValues) {
|
||||||
|
try {
|
||||||
|
writeExecutor.execute(() -> sendMessageSync(type, keyValues));
|
||||||
|
} catch (RejectedExecutionException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessageSync(String type, Object... keyValues) {
|
||||||
try {
|
try {
|
||||||
JSONObject object = new JSONObject();
|
JSONObject object = new JSONObject();
|
||||||
object.put("type", type);
|
object.put("type", type);
|
||||||
for (int i = 0; i + 1 < keyValues.length; i += 2) {
|
for (int i = 0; i + 1 < keyValues.length; i += 2) {
|
||||||
object.put(String.valueOf(keyValues[i]), keyValues[i + 1]);
|
object.put(String.valueOf(keyValues[i]), keyValues[i + 1]);
|
||||||
}
|
}
|
||||||
sendJson(object);
|
sendJsonSync(object);
|
||||||
} catch (Exception error) {
|
} catch (Exception error) {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
listener.onError(error.getMessage() == null ? error.toString() : error.getMessage());
|
listener.onError(error.getMessage() == null ? error.toString() : error.getMessage());
|
||||||
@ -268,6 +278,15 @@ final class TerminalSocketClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void closeSocketQuietly() {
|
||||||
|
try {
|
||||||
|
if (socket != null) {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void sendFrame(int opcode, byte[] payload) throws Exception {
|
private void sendFrame(int opcode, byte[] payload) throws Exception {
|
||||||
synchronized (writeLock) {
|
synchronized (writeLock) {
|
||||||
if (output == null) {
|
if (output == null) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user