Receiving objects from server on separate thread
This commit is contained in:
parent
0efc8dbbc7
commit
c06a2e8c37
@ -1,7 +1,5 @@
|
|||||||
package envoy.client;
|
package envoy.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -9,6 +7,7 @@ import java.util.logging.Logger;
|
|||||||
import envoy.client.util.EnvoyLog;
|
import envoy.client.util.EnvoyLog;
|
||||||
import envoy.data.LoginCredentials;
|
import envoy.data.LoginCredentials;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
|
import envoy.exception.EnvoyException;
|
||||||
import envoy.util.SerializationUtils;
|
import envoy.util.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +24,8 @@ public class Client {
|
|||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private Config config = Config.getInstance();
|
private Config config = Config.getInstance();
|
||||||
private User sender, recipient;
|
private volatile User sender;
|
||||||
|
private User recipient;
|
||||||
private boolean online;
|
private boolean online;
|
||||||
|
|
||||||
private static final Logger logger = EnvoyLog.getLogger(Client.class.getSimpleName());
|
private static final Logger logger = EnvoyLog.getLogger(Client.class.getSimpleName());
|
||||||
@ -34,11 +34,11 @@ public class Client {
|
|||||||
* Enters the online mode by acquiring a user ID from the server.
|
* Enters the online mode by acquiring a user ID from the server.
|
||||||
*
|
*
|
||||||
* @param credentials the login credentials of the user
|
* @param credentials the login credentials of the user
|
||||||
* @throws IOException if the online mode could not be entered or the request
|
* @throws Exception if the online mode could not be entered or the request
|
||||||
* failed for some other reason
|
* failed for some other reason
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void onlineInit(LoginCredentials credentials) throws IOException {
|
public void onlineInit(LoginCredentials credentials) throws Exception {
|
||||||
logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
|
logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
|
||||||
socket = new Socket(config.getServer(), config.getPort());
|
socket = new Socket(config.getServer(), config.getPort());
|
||||||
logger.info("Successfully connected to server.");
|
logger.info("Successfully connected to server.");
|
||||||
@ -47,14 +47,20 @@ public class Client {
|
|||||||
logger.finest("Sending login credentials...");
|
logger.finest("Sending login credentials...");
|
||||||
SerializationUtils.writeBytesWithLength(credentials, socket.getOutputStream());
|
SerializationUtils.writeBytesWithLength(credentials, socket.getOutputStream());
|
||||||
|
|
||||||
// Read response (user object)
|
// Create message receiver
|
||||||
InputStream in = socket.getInputStream();
|
Receiver receiver = new Receiver(socket.getInputStream());
|
||||||
|
|
||||||
// Read object
|
// Register user creation processor
|
||||||
try {
|
receiver.registerProcessor(User.class, sender -> { logger.info("Acquired user object " + sender); this.sender = sender; });
|
||||||
sender = SerializationUtils.read(in, User.class);
|
|
||||||
} catch (ClassNotFoundException e) {
|
// Start receiver
|
||||||
throw new IOException(e);
|
new Thread(receiver).start();
|
||||||
|
|
||||||
|
// Wait for a maximum of five seconds to acquire the sender object
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
while (sender == null) {
|
||||||
|
if (System.currentTimeMillis() - start > 5000) throw new EnvoyException("Did not log in after 5 seconds");
|
||||||
|
Thread.sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
online = true;
|
online = true;
|
||||||
|
15
src/main/java/envoy/client/ObjectProcessor.java
Normal file
15
src/main/java/envoy/client/ObjectProcessor.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package envoy.client;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-client</strong><br>
|
||||||
|
* File: <strong>ObjectProcessor.java</strong><br>
|
||||||
|
* Created: <strong>30.12.2019</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
public interface ObjectProcessor<T> {
|
||||||
|
|
||||||
|
void process(T input);
|
||||||
|
}
|
50
src/main/java/envoy/client/Receiver.java
Normal file
50
src/main/java/envoy/client/Receiver.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package envoy.client;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import envoy.client.util.EnvoyLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-client</strong><br>
|
||||||
|
* File: <strong>Receiver.java</strong><br>
|
||||||
|
* Created: <strong>30.12.2019</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
public class Receiver implements Runnable {
|
||||||
|
|
||||||
|
private InputStream in;
|
||||||
|
private Map<Class<?>, ObjectProcessor<?>> processors = new HashMap<>();
|
||||||
|
|
||||||
|
private static final Logger logger = EnvoyLog.getLogger(Receiver.class.getSimpleName());
|
||||||
|
|
||||||
|
public Receiver(InputStream in) { this.in = in; }
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try (ObjectInputStream oin = new ObjectInputStream(in)) {
|
||||||
|
while (true) {
|
||||||
|
Object obj = oin.readObject();
|
||||||
|
logger.finest("Received object " + obj);
|
||||||
|
|
||||||
|
// Get appropriate processor
|
||||||
|
ObjectProcessor processor = processors.get(obj.getClass());
|
||||||
|
if (processor == null)
|
||||||
|
logger.severe(String.format("The received object has the class %s for which no processor is defined.", obj.getClass()));
|
||||||
|
else
|
||||||
|
processor.process(obj);
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Error on receiver thread", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void registerProcessor(Class<T> processorClass, ObjectProcessor<T> processor) { processors.put(processorClass, processor); }
|
||||||
|
}
|
@ -101,6 +101,7 @@ public class Startup {
|
|||||||
client.onlineInit(new LoginCredentials(userName, pass.toCharArray()));
|
client.onlineInit(new LoginCredentials(userName, pass.toCharArray()));
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
logger.warning("Could not connect to server. Trying offline mode...");
|
logger.warning("Could not connect to server. Trying offline mode...");
|
||||||
|
e1.printStackTrace();
|
||||||
try {
|
try {
|
||||||
// Try entering offline mode
|
// Try entering offline mode
|
||||||
localDB.loadUsers();
|
localDB.loadUsers();
|
||||||
|
Reference in New Issue
Block a user