every message is sent via the sendMsgToClient / sendMsgToServer methods. Logger for debugging what happens when someone accidentally quits

This commit is contained in:
Jonas 2022-04-07 11:33:06 +02:00
parent f26bdec457
commit 02c0676ecf
6 changed files with 28 additions and 46 deletions

View File

@ -61,7 +61,7 @@ public class Client {
String formattedMSG = MessageFormatter.formatMsg(msg); String formattedMSG = MessageFormatter.formatMsg(msg);
sendMsgToServer(formattedMSG); sendMsgToServer(formattedMSG);
} }
Thread.sleep(20); Thread.sleep(5);
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -91,7 +91,8 @@ public class Client {
parse(chatMsg); //todo: i think this trows an error BC chatMsg is null if client disconnects 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();
LOGGER.debug("Exception while trying to read message");
} }
} }
@ -111,7 +112,8 @@ public class Client {
out.newLine(); out.newLine();
out.flush(); out.flush();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); //e.printStackTrace();
LOGGER.debug("unable to send msg: " + msg);
} }
} }
@ -126,7 +128,6 @@ public class Client {
} }
public void closeEverything() { public void closeEverything() {
//TODO Correctly closing a clients connection
try { try {
if (in != null) { if (in != null) {
in.close(); in.close();

View File

@ -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.server.ClientHandler;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
@ -19,19 +20,18 @@ public class ServerPinger implements Runnable {
private boolean gotPingBack; //should be set to true (via setGotPingBack) as soon as the server gets a pingback. private boolean gotPingBack; //should be set to true (via setGotPingBack) as soon as the server gets a pingback.
private boolean isConnected; //set to true unless the ServerPinger detects a connection loss. private boolean isConnected; //set to true unless the ServerPinger detects a connection loss.
BufferedWriter out; //the output of this client through which the pings are sent BufferedWriter out; //the output of this client through which the pings are sent
ClientHandler c;
private Socket socket; private Socket socket;
/** /**
* @param socket the socket the ClientHandler is connected to; used to end the thread if the * @param socket the socket the ClientHandler is connected to; used to end the thread if the
* connection is lost. * connection is closed.
*
* @param out the output through which the pings are sent.
*/ */
public ServerPinger(BufferedWriter out, Socket socket) { public ServerPinger(Socket socket, ClientHandler c) {
gotPingBack = false; gotPingBack = false;
isConnected = true; isConnected = true;
this.out = out;
this.socket = socket; this.socket = socket;
this.c = c;
} }
@Override @Override
@ -40,24 +40,22 @@ public class ServerPinger implements Runnable {
Thread.sleep(2000); Thread.sleep(2000);
while (socket.isConnected() && !socket.isClosed()) { while (socket.isConnected() && !socket.isClosed()) {
gotPingBack = false; gotPingBack = false;
out.write("SPING"); //todo: throws exception when client disconnects. c.sendMsgToClient("SPING");
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.
isConnected = true; isConnected = true;
System.out.println("Connection regained!"); System.out.println("Connection to user " + c.getClientUserName() + " regained!");
} }
} else { } else {
if (isConnected) { if (isConnected) {
isConnected = false; isConnected = false;
System.out.println("Lost connection. Waiting to reconnect..."); System.out.println("Lost connection to user " + c.getClientUserName() + ". Waiting to reconnect...");
} }
} }
} }
isConnected = false; //in case the socket accidentally disconnects (can this happen?) isConnected = false; //in case the socket accidentally disconnects (can this happen?)
} catch (InterruptedException | IOException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -34,18 +34,9 @@ public class ClientHandler implements Runnable {
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())));
this.clientUserName = "Mysterious Passenger"; //todo: duplicate handling for this this.clientUserName = nameDuplicateChecker.singularName("U.N. Owen");
/*
// todo: duplicate handling more elegantly
if (AllClientNames.allNames("").contains(clientUserName)) {
clientUserName = NameGenerator.randomName(clientUserName);
}
// add username to list of all client names for future duplicate checking
AllClientNames.allNames(clientUserName);
*/
connectedClients.add(this); connectedClients.add(this);
serverPinger = new ServerPinger(out, socket); serverPinger = new ServerPinger(socket, this);
Thread sP = new Thread(serverPinger); Thread sP = new Thread(serverPinger);
sP.start(); sP.start();
} catch (IOException e) { } catch (IOException e) {
@ -94,7 +85,8 @@ public class ClientHandler implements Runnable {
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();
LOGGER.debug("Exception while trying to read message");
break; break;
} }
} }
@ -129,7 +121,7 @@ public class ClientHandler implements Runnable {
} }
/** /**
* Broadcasts a Message to all active clients in the form "Username: @msg" * Broadcasts a chat Message to all active clients in the form "Username: @msg"
* *
* @param msg the Message to be broadcast * @param msg the Message to be broadcast
*/ */
@ -141,9 +133,9 @@ public class ClientHandler implements Runnable {
/** /**
* Broadcasts a non-chat Message to all active clients. This can be used for server * Broadcasts a non-chat Message to all active clients. This can be used for server
* messages / announcements rather than chat messages. The message will be printed to the user ex- * messages / announcements rather than chat messages. The message will be printed to the user
* actly as it is given to this method. Unlike broadcastChatMessage, it will also be printed onto * exactly as it is given to this method. Unlike broadcastChatMessage, it will also be printed
* the server console. * onto the server console.
* *
* @param msg the Message to be broadcast * @param msg the Message to be broadcast
*/ */
@ -165,24 +157,19 @@ public class ClientHandler implements Runnable {
out.newLine(); out.newLine();
out.flush(); out.flush();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); //e.printStackTrace();
LOGGER.debug("unable to send msg: " + msg);
} }
} }
/**
* Does what it sounds like
*/
public void removeClientHandler() {
broadcastChatMessage("SERVER: " + clientUserName + " has left the server");
connectedClients.remove(this);
}
/** /**
* Does exactly what it says on the tin, closes all connections of Client to Server. * Does exactly what it says on the tin, closes all connections of Client to Server.
*/ */
public void disconnectClient() { public void disconnectClient() {
broadcastAnnouncement(getClientUserName() + " has left the server.");
sendMsgToClient("QUITC"); sendMsgToClient("QUITC");
removeClientHandler(); connectedClients.remove(this);
socket = this.getSocket(); socket = this.getSocket();
in = this.getIn(); in = this.getIn();
out = this.getOut(); out = this.getOut();

View File

@ -56,7 +56,6 @@ public class JServerProtocolParser {
break; break;
case "QUITS": case "QUITS":
//safely disconnects the user //safely disconnects the user
h.broadcastAnnouncement(h.getClientUserName() + " has left the server.");
h.disconnectClient(); h.disconnectClient();
break; break;
default: default:

View File

@ -27,7 +27,7 @@ public class Server {
*/ */
public void startServer() { public void startServer() {
try { try {
System.out.println("Port 42069 is open on " + this.serverSocket.getInetAddress()); System.out.println("Port 42069 is open on " + this.serverSocket.getInetAddress()); //TODO: this is always 0.0.0.0
while (!serverSocket.isClosed()) { while (!serverSocket.isClosed()) {
Socket socket = serverSocket.accept(); Socket socket = serverSocket.accept();
ClientHandler nextClient = new ClientHandler(socket); ClientHandler nextClient = new ClientHandler(socket);
@ -62,7 +62,4 @@ public class Server {
server.startServer(); server.startServer();
} }
public static void broadcast(String msg) {
//TODO
}
} }

View File

@ -54,7 +54,7 @@ public class nameDuplicateChecker {
public static String singularName(String name) { public static String singularName(String name) {
String rtrn = name; //if this line is used, only duplicate names get a suffix. String rtrn = name; //if this line is used, only duplicate names get a suffix.
//String rtrn = extendName(name); //if this line is used, all clients get a suffix //String rtrn = extendName(name); //if this line is used, all clients get a suffix
while (isTaken(rtrn)) { while (isTaken(rtrn)) { //todo: handle the (very unlikely) case that all names are taken.
rtrn = extendName(name); rtrn = extendName(name);
} }
return rtrn; return rtrn;