Skip to content

Commit

Permalink
Code Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
isHarryh committed Feb 7, 2024
1 parent 3253706 commit 6dab6bb
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 204 deletions.
1 change: 1 addition & 0 deletions core/src/cn/harryh/arkpets/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public final class Const {
// Socket C/S constants
public static final String serverHost = "localhost";
public static final int[] serverPorts = {8686, 8866, 8989, 8899, 8800};
public static final int reconnectDelayMillis = 5 * 1000;
public static final int reconnectPeriodMillis = 5 * 1000;

// Misc constants
Expand Down
4 changes: 2 additions & 2 deletions core/src/cn/harryh/arkpets/concurrent/PortUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public static int getServerPort(int[] expectedPorts)
socket.setSoTimeout(100);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println(JSONObject.toJSONString(new SocketData(UUID.randomUUID(), SocketData.Operation.VERIFY)));
out.println(SocketData.ofOperation(UUID.randomUUID(), SocketData.Operation.HANDSHAKE_REQUEST));
SocketData socketData = JSONObject.parseObject(in.readLine(), SocketData.class);
out.close();
in.close();
if (socketData.operation == SocketData.Operation.SERVER_ONLINE)
if (socketData.operation == SocketData.Operation.HANDSHAKE_RESPONSE)
return serverPort;
} catch (IOException ignored) {
}
Expand Down
32 changes: 22 additions & 10 deletions core/src/cn/harryh/arkpets/concurrent/ProcessPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import java.util.concurrent.*;


public class ProcessPool {
public static final ExecutorService executorService =
public final class ProcessPool implements Executor {
private final ExecutorService executorService =
new ThreadPoolExecutor(20,
Integer.MAX_VALUE,
60L,
Expand All @@ -30,12 +30,25 @@ public static synchronized ProcessPool getInstance() {
private ProcessPool() {
}

public Future<?> submit(Runnable task) {
return executorService.submit(task);
@Override
public void execute(Runnable task) {
try {
executorService.submit(task);
} catch (RejectedExecutionException ignored) {
}
}

public void shutdown() {
executorService.shutdown();
}

public void submitThread(Runnable task)
throws InterruptedException, ExecutionException {
executorService.submit(task).get();
}

public FutureTask<ProcessResult> submit(Class<?> clazz, List<String> jvmArgs, List<String> args) {
Callable<ProcessResult> task = () -> {
public Future<ProcessResult> submitProcess(Class<?> clazz, List<String> jvmArgs, List<String> args) {
FutureTask<ProcessResult> task = new FutureTask<> (() -> {
// Attributes preparation
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
Expand All @@ -56,10 +69,9 @@ public FutureTask<ProcessResult> submit(Class<?> clazz, List<String> jvmArgs, Li
Process process = builder.inheritIO().start();
int exitValue = process.waitFor();
return new ProcessResult(exitValue, process.pid());
};
FutureTask<ProcessResult> futureTask = new FutureTask<>(task);
executorService.submit(futureTask);
return futureTask;
});
executorService.submit(task);
return task;
}


Expand Down
74 changes: 40 additions & 34 deletions core/src/cn/harryh/arkpets/concurrent/SocketClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,42 @@

public class SocketClient {
private boolean connected = false;
private Socket socket;
private SocketSession session;
private Timer timer;

public SocketClient() {
}

public void connectWithRetry(Runnable onConnected) {
public void connectWithRetry(Runnable onConnected, SocketSession session) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
connect(onConnected);
if (connected)
timer.cancel();
}
}, 0, reconnectPeriodMillis);
@Override
public void run() {
connect(onConnected, session);
if (connected)
timer.cancel();
}
},
reconnectDelayMillis,
reconnectPeriodMillis
);
}

public void connect(Runnable onConnected) {
public void connect(Runnable onConnected, SocketSession session) {
if (connected)
return;
try {
int port = PortUtils.getServerPort(serverPorts);
Logger.info("SocketClient", "Connecting to server on port" + port);
Logger.info("SocketClient", "Connecting to server on port " + port);
try {
socket = new Socket(serverHost, port);
Socket socket = new Socket(serverHost, port);
connected = true;
if (this.session != null)
this.session.close();
session.setTarget(socket);
ProcessPool.getInstance().execute(session);
this.session = session;
Logger.info("SocketClient", "(+)" + session + " connected");
if (onConnected != null)
onConnected.run();
} catch (IOException e) {
Expand All @@ -54,28 +62,20 @@ public void connect(Runnable onConnected) {
}
}

public void setHandler(SocketSession session) {
if (!connected)
throw new IllegalStateException("The socket was not yet connected.");
if (this.session != null)
this.session.close();
Thread listener = new Thread(() -> ProcessPool.executorService.execute(session));
ProcessPool.executorService.execute(listener);
this.session = session;
public void disconnect() {
if (connected)
connected = false;
if (session != null)
session.close();
}

public void disconnect() {
if (!connected)
return;
connected = false;
session.close();
public boolean isConnected() {
return connected;
}

public void sendRequest(SocketData socketData) {
if (!connected)
return;
String data = JSONObject.toJSONString(socketData);
session.send(data);
if (connected && session != null)
session.send(JSONObject.toJSONString(socketData));
}


Expand All @@ -85,20 +85,20 @@ public static class ClientSocketSession extends SocketSession {
private UUID uuid = null;

public ClientSocketSession(SocketClient client, MemberTrayImpl memberTray) {
super(client.socket);
super();
this.client = client;
this.memberTray = memberTray;
}

@Override
public void receive(String request) {
try {
SocketData socketData = JSONObject.parseObject(request, SocketData.class);
if (socketData.operation == null)
SocketData socketData = SocketData.of(request);
if (socketData == null || socketData.operation == null)
return;
if (uuid == null)
uuid = socketData.uuid;
if (socketData.uuid.compareTo(this.uuid) == 0) {
if (socketData.uuid.compareTo(this.uuid) == 0 && memberTray != null) {
// If the connection is normal:
switch (socketData.operation) {
case LOGOUT -> memberTray.onExit();
Expand All @@ -113,11 +113,17 @@ public void receive(String request) {
}
}

@Override
protected void onClosed() {
Logger.info("SocketClient", "(-)" + this + " closed");
}

@Override
protected void onBroken() {
Logger.info("SocketClient", "(x)" + this + " broken");
memberTray.onDisconnected();
client.disconnect();
client.connectWithRetry(memberTray::onReconnected);
client.connectWithRetry(memberTray::onConnected, new ClientSocketSession(client, memberTray));
}
}
}
62 changes: 51 additions & 11 deletions core/src/cn/harryh/arkpets/concurrent/SocketData.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package cn.harryh.arkpets.concurrent;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;

import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.UUID;
Expand All @@ -13,25 +16,62 @@ public enum Operation {
NO_KEEP_ACTION,
TRANSPARENT_MODE,
NO_TRANSPARENT_MODE,
CAN_CHANGE_STAGE,
CHANGE_STAGE,
VERIFY,
SERVER_ONLINE,
HANDSHAKE_REQUEST,
HANDSHAKE_RESPONSE,
ACTIVATE_LAUNCHER
}

public UUID uuid;
public Operation operation;
public byte[] name;
public boolean canChangeStage;
public StringDTO msg;

protected SocketData(UUID uuid, Operation operation, StringDTO msg) {
this.uuid = uuid;
this.operation = operation;
this.msg = msg;
}

@JSONField(serialize = false, deserialize = false)
public String getMsgString() {
return msg.toString();
}

@Override
public String toString() {
return JSONObject.toJSONString(this);
}

public SocketData(UUID uuid, Operation operation) {
this(uuid, operation, "", false);
public static SocketData of(String jsonString) {
return JSONObject.parseObject(jsonString, SocketData.class);
}

public SocketData(UUID uuid, Operation operation, String name, boolean canChangeStage) {
this.uuid = uuid;
this.operation = operation;
this.name = name.getBytes(Charset.forName("GBK"));
this.canChangeStage = canChangeStage;
public static SocketData ofLogin(UUID uuid, String name) {
return new SocketData(uuid, Operation.LOGIN, StringDTO.of(name));
}

public static SocketData ofOperation(UUID uuid, Operation operation) {
return new SocketData(uuid, operation, null);
}


protected static class StringDTO {
public byte[] bytes;
public String encoding;

protected StringDTO(byte[] bytes, String encoding) {
this.bytes = bytes;
this.encoding = encoding;
}

@Override
public String toString() {
return new String(bytes, Charset.forName(encoding));
}

public static StringDTO of(String string) {
return new StringDTO(string.getBytes(Charset.defaultCharset()), Charset.defaultCharset().name());
}
}
}
Loading

0 comments on commit 6dab6bb

Please sign in to comment.