Receiving objects from server on separate thread
This commit is contained in:
parent
61d3d44ee5
commit
e66dba8812
@ -1,7 +1,5 @@
|
||||
package envoy.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
@ -9,6 +7,7 @@ import java.util.logging.Logger;
|
||||
import envoy.client.util.EnvoyLog;
|
||||
import envoy.data.LoginCredentials;
|
||||
import envoy.data.User;
|
||||
import envoy.exception.EnvoyException;
|
||||
import envoy.util.SerializationUtils;
|
||||
|
||||
/**
|
||||
@ -23,10 +22,11 @@ import envoy.util.SerializationUtils;
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
private Socket socket;
|
||||
private Config config = Config.getInstance();
|
||||
private User sender, recipient;
|
||||
private boolean online;
|
||||
private Socket socket;
|
||||
private Config config = Config.getInstance();
|
||||
private volatile User sender;
|
||||
private User recipient;
|
||||
private boolean online;
|
||||
|
||||
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.
|
||||
*
|
||||
* @param credentials the login credentials of the user
|
||||
* @throws IOException if the online mode could not be entered or the request
|
||||
* failed for some other reason
|
||||
* @throws Exception if the online mode could not be entered or the request
|
||||
* failed for some other reason
|
||||
* @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()));
|
||||
socket = new Socket(config.getServer(), config.getPort());
|
||||
logger.info("Successfully connected to server.");
|
||||
@ -47,14 +47,20 @@ public class Client {
|
||||
logger.finest("Sending login credentials...");
|
||||
SerializationUtils.writeBytesWithLength(credentials, socket.getOutputStream());
|
||||
|
||||
// Read response (user object)
|
||||
InputStream in = socket.getInputStream();
|
||||
// Create message receiver
|
||||
Receiver receiver = new Receiver(socket.getInputStream());
|
||||
|
||||
// Read object
|
||||
try {
|
||||
sender = SerializationUtils.read(in, User.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IOException(e);
|
||||
// Register user creation processor
|
||||
receiver.registerProcessor(User.class, sender -> { logger.info("Acquired user object " + sender); this.sender = sender; });
|
||||
|
||||
// Start receiver
|
||||
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;
|
||||
|
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()));
|
||||
} catch (Exception e1) {
|
||||
logger.warning("Could not connect to server. Trying offline mode...");
|
||||
e1.printStackTrace();
|
||||
try {
|
||||
// Try entering offline mode
|
||||
localDB.loadUsers();
|
||||
|
Reference in New Issue
Block a user