complete overhaul of client / server communication. Several methods renamed, tweaked protocol.
This commit is contained in:
parent
52a6a0cd65
commit
f677f5cb71
@ -16,7 +16,7 @@ public class BudaLogConfig {
|
|||||||
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||||
Configuration config = ctx.getConfiguration();
|
Configuration config = ctx.getConfiguration();
|
||||||
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
||||||
loggerConfig.setLevel(Level.TRACE); // change level here
|
loggerConfig.setLevel(Level.DEBUG); // change level here
|
||||||
ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig.
|
ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ClientPinger;
|
|||||||
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -27,14 +28,9 @@ public class Client {
|
|||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
||||||
this.in = new BufferedReader((new InputStreamReader((socket.getInputStream()))));
|
this.in = new BufferedReader((new InputStreamReader((socket.getInputStream()))));
|
||||||
|
|
||||||
//TODO add the system based generated username here.
|
|
||||||
//TODO hide connecting logik(next 4 lines)
|
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.out.write(getUsername());
|
sendMsgToServer(getUsername());
|
||||||
this.out.newLine();
|
clientPinger = new ClientPinger(this, this.socket);
|
||||||
this.out.flush();
|
|
||||||
clientPinger = new ClientPinger(this.out, this.socket);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
closeEverything(socket, in, out);
|
closeEverything(socket, in, out);
|
||||||
@ -44,20 +40,19 @@ public class Client {
|
|||||||
/**
|
/**
|
||||||
* Sends a message to the Server in a formatted way COMND$msg
|
* Sends a message to the Server in a formatted way COMND$msg
|
||||||
*/
|
*/
|
||||||
public void sendMessage() {
|
public void userInputListener() {
|
||||||
try {
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
Scanner sc = new Scanner(System.in);
|
Scanner sc = new Scanner(System.in);
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected() && !socket.isClosed()) {
|
||||||
String msg = sc.nextLine();
|
String msg = sc.nextLine();
|
||||||
String formattedMSG = MessageFormatter.formatMsg(msg);
|
String formattedMSG = MessageFormatter.formatMsg(msg);
|
||||||
out.write(formattedMSG);
|
sendMsgToServer(formattedMSG);
|
||||||
out.newLine();
|
|
||||||
out.flush();
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
LOGGER.debug("userInputListener is done");
|
||||||
e.printStackTrace();
|
|
||||||
closeEverything(socket, in, out);
|
|
||||||
}
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,16 +69,19 @@ public class Client {
|
|||||||
|
|
||||||
String chatMsg;
|
String chatMsg;
|
||||||
|
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected() && !socket.isClosed()) {
|
||||||
try {
|
try {
|
||||||
chatMsg = in.readLine();
|
chatMsg = in.readLine();
|
||||||
parse(chatMsg);
|
if (chatMsg != null) {
|
||||||
|
parse(chatMsg); //todo: i think this trows an error BC chatMsg is null if client disconnects
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
closeEverything(socket, in, out);
|
closeEverything(socket, in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
LOGGER.debug("chatListener is done");
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
@ -152,7 +150,7 @@ public class Client {
|
|||||||
client.chatListener();
|
client.chatListener();
|
||||||
Thread cP = new Thread(client.clientPinger);
|
Thread cP = new Thread(client.clientPinger);
|
||||||
cP.start();
|
cP.start();
|
||||||
client.sendMessage(); //this one blocks.
|
client.userInputListener(); //this one blocks.
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
System.out.println("Invalid host IP");
|
System.out.println("Invalid host IP");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@ -38,6 +38,9 @@ public class JClientProtocolParser {
|
|||||||
*/
|
*/
|
||||||
System.out.println(msg.substring(6));
|
System.out.println(msg.substring(6));
|
||||||
break;
|
break;
|
||||||
|
case "QUITC":
|
||||||
|
//c.closeEverything(); todo: this line.
|
||||||
|
System.out.println("bye!");
|
||||||
default:
|
default:
|
||||||
System.out.println("Received unknown command");
|
System.out.println("Received unknown command");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,16 +19,20 @@ public class MessageFormatter {
|
|||||||
public static String formatMsg(String msg) {
|
public static String formatMsg(String msg) {
|
||||||
String header = ""; //header is first two characters
|
String header = ""; //header is first two characters
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
String s; // just a friendly helper to save message in
|
String s = ""; // just a friendly helper to save message in
|
||||||
try {
|
try {
|
||||||
header = msg.substring(0, 2);
|
header = msg.substring(0, 2);
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
e.printStackTrace();
|
header = "";
|
||||||
}
|
}
|
||||||
switch (header) {
|
switch (header) {
|
||||||
case "/c":
|
case "/c":
|
||||||
stringBuilder.append("CHATA$");
|
stringBuilder.append("CHATA$");
|
||||||
|
try {
|
||||||
s = msg.substring(3);
|
s = msg.substring(3);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("You didn't even write a chat line, you silly billy!");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "/q":
|
case "/q":
|
||||||
stringBuilder.append("QUITS$");
|
stringBuilder.append("QUITS$");
|
||||||
@ -36,7 +40,11 @@ public class MessageFormatter {
|
|||||||
break;
|
break;
|
||||||
case "/n":
|
case "/n":
|
||||||
stringBuilder.append("NAMEC$");
|
stringBuilder.append("NAMEC$");
|
||||||
|
try {
|
||||||
s = msg.substring(3);
|
s = msg.substring(3);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Well what do you want your name to be?");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s = msg;
|
s = msg;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.multiplayer.helpers;
|
package ch.unibas.dmi.dbis.cs108.multiplayer.helpers;
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
|
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.multiplayer.client.Client;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@ -18,19 +19,17 @@ public class ClientPinger implements Runnable {
|
|||||||
|
|
||||||
private boolean gotPingBack; //should be set to true when client gets a pingback.
|
private boolean gotPingBack; //should be set to true when client gets a pingback.
|
||||||
private boolean isConnected; //set to true unless the ClientPinger detects a connection loss.
|
private boolean isConnected; //set to true unless the ClientPinger detects a connection loss.
|
||||||
BufferedWriter out; //the output of this client through which the pings are sent
|
private final Client client;
|
||||||
private Socket socket;
|
private final Socket socket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param socket the socket the Client is connected to which is used to end the thread if the
|
* @param socket the socket the Client is connected to which is used to end the thread if the
|
||||||
* connection is lost.
|
* connection is lost.
|
||||||
*
|
|
||||||
* @param out the output through which the pings are sent.
|
|
||||||
*/
|
*/
|
||||||
public ClientPinger(BufferedWriter out, Socket socket) {
|
public ClientPinger(Client client, Socket socket) {
|
||||||
gotPingBack = false;
|
gotPingBack = false;
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
this.out = out;
|
this.client = client;
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,11 +37,9 @@ public class ClientPinger implements Runnable {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected() && !socket.isClosed()) {
|
||||||
gotPingBack = false;
|
gotPingBack = false;
|
||||||
out.write("CPING");
|
client.sendMsgToServer("CPING");
|
||||||
out.newLine();
|
|
||||||
out.flush();
|
|
||||||
Thread.sleep(4000);
|
Thread.sleep(4000);
|
||||||
if (gotPingBack) {
|
if (gotPingBack) {
|
||||||
if (!isConnected) { //if !isConnected, then the connection had been lost before.
|
if (!isConnected) { //if !isConnected, then the connection had been lost before.
|
||||||
@ -56,8 +53,8 @@ public class ClientPinger implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isConnected = false; //in case the socket accidentally disconnects (can this happen?)
|
isConnected = false;
|
||||||
} catch (InterruptedException | IOException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,10 @@ Client commands:
|
|||||||
|
|
||||||
Implemented:
|
Implemented:
|
||||||
* CHATA$message Send chat message to all
|
* CHATA$message Send chat message to all
|
||||||
* QUITS quit server/ leave server
|
* QUITS request to quit server/ leave server. The server should then remove the
|
||||||
|
relevant ClientHandler and close the sockets, but before doing so, it sends
|
||||||
|
"QUITC" to the client to confirm the quitting. The client doesn't close any
|
||||||
|
sockets until receiving "QUITC"
|
||||||
* CPING Ping from client to server.
|
* CPING Ping from client to server.
|
||||||
* PINGB Pingback from client to server.
|
* PINGB Pingback from client to server.
|
||||||
* NAMEC$name Change name to whatever is specified
|
* NAMEC$name Change name to whatever is specified
|
||||||
@ -22,6 +25,7 @@ Server Commands:
|
|||||||
Implemented:
|
Implemented:
|
||||||
* SPING Ping from server to client
|
* SPING Ping from server to client
|
||||||
* PINGB Pingback from client to server.
|
* PINGB Pingback from client to server.
|
||||||
|
* QUITC Confirms to the client that they are being disconnected from the server.
|
||||||
|
|
||||||
Future / planned:
|
Future / planned:
|
||||||
* MSGRS "Message received": Paramaters: a string detailing to the client that and what the server received as command.
|
* MSGRS "Message received": Paramaters: a string detailing to the client that and what the server received as command.
|
||||||
|
|||||||
@ -38,9 +38,9 @@ public class ServerPinger implements Runnable {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected() && !socket.isClosed()) {
|
||||||
gotPingBack = false;
|
gotPingBack = false;
|
||||||
out.write("SPING");
|
out.write("SPING"); //todo: throws exception when client disconnects.
|
||||||
out.newLine();
|
out.newLine();
|
||||||
out.flush();
|
out.flush();
|
||||||
Thread.sleep(4000);
|
Thread.sleep(4000);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ public class ClientHandler implements Runnable {
|
|||||||
private BufferedWriter out;
|
private BufferedWriter out;
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
|
private
|
||||||
Scanner sc;
|
Scanner sc;
|
||||||
public ServerPinger serverPinger;
|
public ServerPinger serverPinger;
|
||||||
public static HashSet<ClientHandler> connectedClients = new HashSet<>();
|
public static HashSet<ClientHandler> connectedClients = new HashSet<>();
|
||||||
@ -44,10 +45,9 @@ public class ClientHandler implements Runnable {
|
|||||||
serverPinger = new ServerPinger(out, socket);
|
serverPinger = new ServerPinger(out, socket);
|
||||||
Thread sP = new Thread(serverPinger);
|
Thread sP = new Thread(serverPinger);
|
||||||
sP.start();
|
sP.start();
|
||||||
broadcastMessage("SERVER: " + clientUserName + " has joined the Server");
|
broadcastChatMessage("SERVER: " + clientUserName + " has joined the Server");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
closeEverything(socket, in, out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +87,12 @@ public class ClientHandler implements Runnable {
|
|||||||
**/
|
**/
|
||||||
public void run() {
|
public void run() {
|
||||||
String msg;
|
String msg;
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected() && !socket.isClosed()) {
|
||||||
try {
|
try {
|
||||||
msg = in.readLine(); //todo: here is where the server throws an exception when the client quits
|
msg = in.readLine(); //todo: here is where the server throws an exception when the client quits
|
||||||
JServerProtocolParser.parse(msg, this);
|
JServerProtocolParser.parse(msg, this);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
closeEverything(socket, in, out);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +115,7 @@ public class ClientHandler implements Runnable {
|
|||||||
String h = this.clientUserName; //just a friendly little helper
|
String h = this.clientUserName; //just a friendly little helper
|
||||||
this.clientUserName = newName;
|
this.clientUserName = newName;
|
||||||
AllClientNames.allNames(newName);
|
AllClientNames.allNames(newName);
|
||||||
broadcastMessage(h + " have changed their nickname to " + clientUserName);
|
broadcastChatMessage(h + " have changed their nickname to " + clientUserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,10 +123,9 @@ public class ClientHandler implements Runnable {
|
|||||||
*
|
*
|
||||||
* @param msg the Message to be broadcasted
|
* @param msg the Message to be broadcasted
|
||||||
*/
|
*/
|
||||||
|
public void broadcastChatMessage(String msg) {
|
||||||
public void broadcastMessage(String msg) {
|
|
||||||
for (ClientHandler client : connectedClients) {
|
for (ClientHandler client : connectedClients) {
|
||||||
client.sendMsgToClient("CHATM:" + clientUserName + ": \"" + msg + "\"");
|
client.sendMsgToClient("CHATM$" + clientUserName + ": \"" + msg + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,9 +133,9 @@ public class ClientHandler implements Runnable {
|
|||||||
* todo: check for exception if out is closed.
|
* todo: check for exception if out is closed.
|
||||||
* @param msg the given message
|
* @param msg the given message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void sendMsgToClient(String msg) {
|
public void sendMsgToClient(String msg) {
|
||||||
try {
|
try {
|
||||||
|
//todo: socket closed handling
|
||||||
out.write(msg);
|
out.write(msg);
|
||||||
out.newLine();
|
out.newLine();
|
||||||
out.flush();
|
out.flush();
|
||||||
@ -150,8 +148,8 @@ public class ClientHandler implements Runnable {
|
|||||||
* Does what it sounds like
|
* Does what it sounds like
|
||||||
*/
|
*/
|
||||||
public void removeClientHandler() {
|
public void removeClientHandler() {
|
||||||
|
broadcastChatMessage("SERVER: " + clientUserName + " has left the server");
|
||||||
connectedClients.remove(this);
|
connectedClients.remove(this);
|
||||||
broadcastMessage("SERVER: " + clientUserName + " has left the server");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,9 +159,14 @@ public class ClientHandler implements Runnable {
|
|||||||
* @param in the in-Stream reader to be closed
|
* @param in the in-Stream reader to be closed
|
||||||
* @param out the out-Stream Write to be closed
|
* @param out the out-Stream Write to be closed
|
||||||
*/
|
*/
|
||||||
public void closeEverything(Socket socket, BufferedReader in, BufferedWriter out) {
|
public void disconnectClient() {
|
||||||
|
sendMsgToClient("QUITC");
|
||||||
removeClientHandler();
|
removeClientHandler();
|
||||||
|
socket = this.getSocket();
|
||||||
|
in = this.getIn();
|
||||||
|
out = this.getOut();
|
||||||
try {
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
@ -173,12 +176,10 @@ public class ClientHandler implements Runnable {
|
|||||||
if (socket != null) {
|
if (socket != null) {
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decodeMsg(String msg) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class JServerProtocolParser {
|
|||||||
switch (header) {
|
switch (header) {
|
||||||
case CHATA:
|
case CHATA:
|
||||||
//sends chat message to all connected clients
|
//sends chat message to all connected clients
|
||||||
h.broadcastMessage(msg.substring(6));
|
h.broadcastChatMessage(msg.substring(6));
|
||||||
break;
|
break;
|
||||||
case "NAMEC":
|
case "NAMEC":
|
||||||
//changes name to whatever follows NAMEC$. If the new name is already in use, it will append
|
//changes name to whatever follows NAMEC$. If the new name is already in use, it will append
|
||||||
@ -47,7 +47,7 @@ public class JServerProtocolParser {
|
|||||||
break;
|
break;
|
||||||
case "QUITS":
|
case "QUITS":
|
||||||
//safely disconnects the user
|
//safely disconnects the user
|
||||||
h.closeEverything(h.getSocket(), h.getIn(), h.getOut());
|
h.disconnectClient();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Received unknown command");
|
System.out.println("Received unknown command");
|
||||||
|
|||||||
Reference in New Issue
Block a user