mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Refactored servercommands, added tcp client, added command queue.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.toop.eventbus;
|
package org.toop.eventbus;
|
||||||
|
|
||||||
import org.toop.server.Server;
|
import org.toop.server.Server;
|
||||||
|
import org.toop.server.ServerCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Events that are used in the GlobalEventBus class.
|
* Events that are used in the GlobalEventBus class.
|
||||||
@@ -12,12 +13,12 @@ public class Events implements IEvents {
|
|||||||
/**
|
/**
|
||||||
* Triggers sending a command to a server.
|
* Triggers sending a command to a server.
|
||||||
*/
|
*/
|
||||||
public record command(Server.Command command, String... args) {}
|
public record command(String command, String... args) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers when a command is sent to a server.
|
* Triggers when a command is sent to a server.
|
||||||
*/
|
*/
|
||||||
public record OnCommand(Server.Command command, String[] args, Server.Message result) {}
|
public record OnCommand(org.toop.server.ServerCommand command, String[] args, String result) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers on changing the server backend.
|
* Triggers on changing the server backend.
|
||||||
|
|||||||
@@ -3,11 +3,17 @@ package org.toop.server;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.toop.Main;
|
import org.toop.Main;
|
||||||
import org.toop.eventbus.EventRegistry;
|
|
||||||
import org.toop.eventbus.Events;
|
import org.toop.eventbus.Events;
|
||||||
import org.toop.eventbus.GlobalEventBus;
|
import org.toop.eventbus.GlobalEventBus;
|
||||||
import org.toop.server.backend.*;
|
import org.toop.server.backend.*;
|
||||||
import java.util.EnumSet;
|
import org.toop.server.backend.local.Local;
|
||||||
|
import org.toop.server.backend.remote.Remote;
|
||||||
|
import org.toop.server.backend.remote.TcpClient;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Server extends Thread {
|
public class Server extends Thread {
|
||||||
|
|
||||||
@@ -18,35 +24,6 @@ public class Server extends Thread {
|
|||||||
REMOTE,
|
REMOTE,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Command {
|
|
||||||
/**
|
|
||||||
* Login, "username"
|
|
||||||
*/
|
|
||||||
LOGIN,
|
|
||||||
/**
|
|
||||||
* Logout, "username"
|
|
||||||
*/
|
|
||||||
LOGOUT,
|
|
||||||
EXIT,
|
|
||||||
QUIT,
|
|
||||||
DISCONNECT,
|
|
||||||
BYE,
|
|
||||||
GET,
|
|
||||||
SUBSCRIBE,
|
|
||||||
MOVE,
|
|
||||||
CHALLENGE,
|
|
||||||
FORFEIT,
|
|
||||||
MESSAGE,
|
|
||||||
HELP,
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final EnumSet<Command> VALID_COMMANDS = EnumSet.of(
|
|
||||||
Command.LOGIN, Command.LOGOUT, Command.EXIT, Command.QUIT,
|
|
||||||
Command.DISCONNECT, Command.BYE, Command.GET, Command.SUBSCRIBE,
|
|
||||||
Command.MOVE, Command.CHALLENGE, Command.FORFEIT,
|
|
||||||
Command.MESSAGE, Command.HELP
|
|
||||||
);
|
|
||||||
|
|
||||||
public enum Message {
|
public enum Message {
|
||||||
OK,
|
OK,
|
||||||
ERR,
|
ERR,
|
||||||
@@ -56,12 +33,14 @@ public class Server extends Thread {
|
|||||||
String ip;
|
String ip;
|
||||||
String port;
|
String port;
|
||||||
IBackend backend;
|
IBackend backend;
|
||||||
|
List<String> commandQueue;
|
||||||
|
|
||||||
public Server(ServerBackend set_backend, String set_ip, String set_port) {
|
public Server(ServerBackend set_backend, String set_ip, String set_port) {
|
||||||
ip = set_ip;
|
ip = set_ip;
|
||||||
port = set_port;
|
port = set_port;
|
||||||
setBackend(set_backend);
|
setBackend(set_backend);
|
||||||
this.initEvents();
|
this.initEvents();
|
||||||
|
this.commandQueue = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBackend getBackend() {
|
public IBackend getBackend() {
|
||||||
@@ -97,61 +76,45 @@ public class Server extends Thread {
|
|||||||
GlobalEventBus.post(new Events.ServerEvents.OnChangingServerPort(port));
|
GlobalEventBus.post(new Events.ServerEvents.OnChangingServerPort(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message sendCommandString(String sentence) {
|
private void sendCommandByString(String command, String... args) {
|
||||||
return Message.OK;
|
if (!ServerCommand.isValid(command)) {
|
||||||
}
|
return;
|
||||||
|
|
||||||
private boolean isCommandValid(Command command) {
|
|
||||||
return VALID_COMMANDS.contains(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a command to the server.
|
|
||||||
*
|
|
||||||
* @param command the command to execute
|
|
||||||
* @return a Message indicating success or error
|
|
||||||
*/
|
|
||||||
public Message sendCommand(Command command) {
|
|
||||||
if (!isCommandValid(command)) {
|
|
||||||
throw new IllegalArgumentException("Invalid command: " + command);
|
|
||||||
}
|
|
||||||
Message result = sendCommandString(command.toString());
|
|
||||||
|
|
||||||
GlobalEventBus.post(new Events.ServerEvents.OnCommand(command, new String[0], result));
|
|
||||||
|
|
||||||
return sendCommandString(command.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a command to the server.
|
|
||||||
*
|
|
||||||
* @param command the command to execute
|
|
||||||
* @param args command arguments.
|
|
||||||
* @return a Message indicating success or error
|
|
||||||
*/
|
|
||||||
public Message sendCommand(Command command, String... args) {
|
|
||||||
if (!isCommandValid(command)) {
|
|
||||||
throw new IllegalArgumentException("Invalid command: " + command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
args[i] = args[i].trim();
|
args[i] = args[i].trim();
|
||||||
if (args[i].isEmpty()) {
|
if (args[i].isEmpty()) {
|
||||||
throw new IllegalArgumentException("Empty argument");
|
throw new IllegalArgumentException("Empty argument"); // TODO: Error handling, just crashes atm.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] fullCommand = new String[args.length + 1];
|
String[] fullCommand = new String[args.length + 1];
|
||||||
fullCommand[0] = command.toString();
|
fullCommand[0] = command;
|
||||||
System.arraycopy(args, 0, fullCommand, 1, args.length);
|
System.arraycopy(args, 0, fullCommand, 1, args.length);
|
||||||
|
|
||||||
Message result = sendCommandString(String.join(" ", fullCommand));
|
this.commandQueue.add(Arrays.toString(fullCommand)); // TODO Dunno if correct
|
||||||
|
|
||||||
GlobalEventBus.post(new Events.ServerEvents.OnCommand(command, args, result));
|
logger.info("Command {} added to the queue", Arrays.toString(fullCommand));
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Sends a command to the server.
|
||||||
|
// *
|
||||||
|
// * @param command the command to execute
|
||||||
|
// * @return a Message indicating success or error
|
||||||
|
// */
|
||||||
|
// public void sendCommand(ServerCommand command) {
|
||||||
|
//
|
||||||
|
// Message result = Message.OK;
|
||||||
|
//
|
||||||
|
// this.commandQueue.add(command.toString());
|
||||||
|
//
|
||||||
|
// GlobalEventBus.post(new Events.ServerEvents.OnCommand(command, new String[0], result));
|
||||||
|
//
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format(
|
return String.format(
|
||||||
@@ -161,18 +124,35 @@ public class Server extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initEvents() {
|
private void initEvents() {
|
||||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.command.class, e -> this.sendCommand(e.command(), e.args()));
|
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.command.class, event
|
||||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.changeServerIp.class, e -> this.setIp(e.ip()));
|
-> this.sendCommandByString(event.command(), event.args()));
|
||||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.changeServerPort.class, e -> this.setPort(e.port()));
|
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.changeServerIp.class, event
|
||||||
|
-> this.setIp(event.ip()));
|
||||||
|
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.changeServerPort.class, event
|
||||||
|
-> this.setPort(event.port()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
try {
|
||||||
|
TcpClient client = new TcpClient(this.getIp(), Integer.parseInt(this.getPort())); // TODO This is unsafe
|
||||||
|
theRemoteServerTimeline(client);
|
||||||
|
} catch (UnknownHostException | InterruptedException e) { // TODO Better error handling.
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void theRemoteServerTimeline(TcpClient client) throws InterruptedException {
|
||||||
while (true) {
|
while (true) {
|
||||||
logger.info("Ik ben Bas, hallo");
|
sleep(500); // 1s delay to not overload server.
|
||||||
try {
|
if (!commandQueue.isEmpty()) {
|
||||||
sleep(1000);
|
String command = commandQueue.removeFirst();
|
||||||
} catch (InterruptedException e) {
|
logger.info("Sending command: {}", command);
|
||||||
throw new RuntimeException(e);
|
try {
|
||||||
|
client.sendMessage(command); // TODO: Will block.
|
||||||
|
client.readLine(); // TODO Does this need to wait?
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO: Error handling.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/main/java/org/toop/server/ServerCommand.java
Normal file
66
src/main/java/org/toop/server/ServerCommand.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package org.toop.server;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public enum ServerCommand {
|
||||||
|
/**
|
||||||
|
* Login, "username"
|
||||||
|
*/
|
||||||
|
LOGIN,
|
||||||
|
/**
|
||||||
|
* Logout, "username"
|
||||||
|
*/
|
||||||
|
LOGOUT,
|
||||||
|
EXIT,
|
||||||
|
QUIT,
|
||||||
|
DISCONNECT,
|
||||||
|
BYE,
|
||||||
|
GET,
|
||||||
|
SUBSCRIBE,
|
||||||
|
MOVE,
|
||||||
|
CHALLENGE,
|
||||||
|
FORFEIT,
|
||||||
|
MESSAGE,
|
||||||
|
HELP;
|
||||||
|
|
||||||
|
private static final EnumSet<ServerCommand> VALID_COMMANDS = EnumSet.of(
|
||||||
|
ServerCommand.LOGIN, ServerCommand.LOGOUT, ServerCommand.EXIT,
|
||||||
|
ServerCommand.QUIT, ServerCommand.DISCONNECT, ServerCommand.BYE,
|
||||||
|
ServerCommand.GET, ServerCommand.SUBSCRIBE, ServerCommand.MOVE,
|
||||||
|
ServerCommand.CHALLENGE, ServerCommand.FORFEIT,
|
||||||
|
ServerCommand.MESSAGE, ServerCommand.HELP
|
||||||
|
);
|
||||||
|
|
||||||
|
public static EnumSet<ServerCommand> getValidCommands() {
|
||||||
|
return VALID_COMMANDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Garbage code.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param command Checks if string is a valid command.
|
||||||
|
* @return returns a boolean if string is a valid command.
|
||||||
|
*/
|
||||||
|
public static boolean isValid(String command) {
|
||||||
|
try {
|
||||||
|
ServerCommand.valueOf(command.toUpperCase());
|
||||||
|
return true;
|
||||||
|
} catch (IllegalArgumentException err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Return something better
|
||||||
|
/**
|
||||||
|
* @param command Converts a string into a ServerCommand.
|
||||||
|
* @return returns a ServerCommand enum.
|
||||||
|
*/
|
||||||
|
public static ServerCommand getCommand(String command) {
|
||||||
|
if (isValid(command)) {
|
||||||
|
ServerCommand.valueOf(command.toUpperCase());
|
||||||
|
return ServerCommand.valueOf(command.toUpperCase());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.toop.server.backend;
|
package org.toop.server.backend.local;
|
||||||
|
|
||||||
import org.toop.server.Server;
|
import org.toop.server.Server;
|
||||||
|
import org.toop.server.backend.IBackend;
|
||||||
|
|
||||||
public class Local implements IBackend {
|
public class Local implements IBackend {
|
||||||
@Override
|
@Override
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.toop.server.backend;
|
package org.toop.server.backend.remote;
|
||||||
|
|
||||||
import org.toop.server.Server;
|
import org.toop.server.Server;
|
||||||
|
import org.toop.server.backend.IBackend;
|
||||||
|
|
||||||
public class Remote implements IBackend {
|
public class Remote implements IBackend {
|
||||||
@Override
|
@Override
|
||||||
56
src/main/java/org/toop/server/backend/remote/TcpClient.java
Normal file
56
src/main/java/org/toop/server/backend/remote/TcpClient.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package org.toop.server.backend.remote;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
public class TcpClient {
|
||||||
|
|
||||||
|
InetAddress serverAddress;
|
||||||
|
int serverPort;
|
||||||
|
Socket socket;
|
||||||
|
BufferedReader in;
|
||||||
|
PrintWriter out;
|
||||||
|
|
||||||
|
public TcpClient(byte[] serverIp, int serverPort) throws IOException {
|
||||||
|
this.serverAddress = InetAddress.getByAddress(serverIp);
|
||||||
|
this.serverPort = serverPort;
|
||||||
|
this.socket = createSocket();
|
||||||
|
this.in = createIn();
|
||||||
|
this.out = createOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TcpClient(String serverIp, int serverPort) throws UnknownHostException {
|
||||||
|
this.serverAddress = InetAddress.getByName(serverIp);
|
||||||
|
this.serverPort = serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Socket createSocket() throws IOException {
|
||||||
|
return new Socket(serverAddress, serverPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedReader createIn() throws IOException {
|
||||||
|
return new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrintWriter createOut() throws IOException {
|
||||||
|
return new PrintWriter(this.socket.getOutputStream(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) throws IOException {
|
||||||
|
this.out.write(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readLine() throws IOException {
|
||||||
|
return this.in.readLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.toop.server.Server;
|
import org.toop.server.Server;
|
||||||
import org.toop.server.backend.*;
|
import org.toop.server.backend.local.Local;
|
||||||
|
import org.toop.server.backend.remote.Remote;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user