Hallo zusammen,
müssen an der Uni einen Multiplayer Spiel ähnlich Diablo programmieren. Der Client wird dabei in einem Fenster (JFrame) angezeigt/ausgeführt.
Meine Frage ist jetzt, wie ich dem Server am geschicktesten mitteile, dass der Client sich "abmeldet" wenn auf den schließen button gedrückt wird. Habe mir das mit einem ShutdownHook überlegt (später will ich evtl noch "keepalive" messages einbauen). Hab das jetzt so implementiert, das der Client also im sterben noch eine "ich bin weg" message an den server schickt.
Dieser wiederum hat für jeden Client jeweils einen NetworkHandler, NetworkReceiver und NetworkTransmitter (alles eigene Threads). Die NetworkHandler werden in einer LinkedList verwaltet und repräsentieren einen Client auf technischer Ebene, ClientID ist die Position in der Liste. Nun ist die frage, wie ich einen Client abmelde, bzw aus der Liste schmeiße. Muss nur auf dieser technischen Ebene sein, also nicht fürs spiel. In NetworkReceiver werden Strings aus dem Socket gelesen und dann in die engineQueue oder chatQueue sortiert per Schlüsselwerten.
Dort kommt jetzt ein String "XX|EXIT" (XX = ClientID) und ich schließe das Socket, aber wie gebe ich das nach oben weiter, lösche den entsprechenden NetworkHandler und beende die Threads?
Kann ich das einfach hier in der Endlosschleife machen? Gibt es dann Konflikte mit der statischen Methode distributor() oder kann ich da auch unstatisch nebenbei auf das socket.isClosed() prüfen?
oder kann man evtl sogar eine Art statischen Thread und Thread auf das Obkjekt draus bauen?
müssen an der Uni einen Multiplayer Spiel ähnlich Diablo programmieren. Der Client wird dabei in einem Fenster (JFrame) angezeigt/ausgeführt.
Meine Frage ist jetzt, wie ich dem Server am geschicktesten mitteile, dass der Client sich "abmeldet" wenn auf den schließen button gedrückt wird. Habe mir das mit einem ShutdownHook überlegt (später will ich evtl noch "keepalive" messages einbauen). Hab das jetzt so implementiert, das der Client also im sterben noch eine "ich bin weg" message an den server schickt.
Dieser wiederum hat für jeden Client jeweils einen NetworkHandler, NetworkReceiver und NetworkTransmitter (alles eigene Threads). Die NetworkHandler werden in einer LinkedList verwaltet und repräsentieren einen Client auf technischer Ebene, ClientID ist die Position in der Liste. Nun ist die frage, wie ich einen Client abmelde, bzw aus der Liste schmeiße. Muss nur auf dieser technischen Ebene sein, also nicht fürs spiel. In NetworkReceiver werden Strings aus dem Socket gelesen und dann in die engineQueue oder chatQueue sortiert per Schlüsselwerten.
Dort kommt jetzt ein String "XX|EXIT" (XX = ClientID) und ich schließe das Socket, aber wie gebe ich das nach oben weiter, lösche den entsprechenden NetworkHandler und beende die Threads?
Kann ich das einfach hier in der Endlosschleife machen? Gibt es dann Konflikte mit der statischen Methode distributor() oder kann ich da auch unstatisch nebenbei auf das socket.isClosed() prüfen?
oder kann man evtl sogar eine Art statischen Thread und Thread auf das Obkjekt draus bauen?
Java:
public class NetworkHandler implements Runnable {
private ExecutorService threadPool;
private String clientID;
private Socket client;
private LinkedBlockingQueue<String> outputQueue; // Messages zu einem bestimmten Client
private LinkedBlockingQueue<String> engineMessages; //Messages zur Server Engine
private LinkedBlockingQueue<String> chatMessages; //Messages zur Chatroutine
private static LinkedBlockingQueue<String> outputMessages; //Messages des Servers an irgendwelche Clients
private static LinkedList<NetworkHandler> clientPool;
public NetworkHandler(ExecutorService pThreadPool, Socket pClient,
LinkedBlockingQueue<String> pChatMessages,
LinkedBlockingQueue<String> pEngineMessages,
LinkedBlockingQueue<String> pOutputMessages,
LinkedList<NetworkHandler> pClientPool) {
this.threadPool = pThreadPool;
this.client = pClient;
this.engineMessages = pEngineMessages;
this.chatMessages = pChatMessages;
NetworkHandler.outputMessages = pOutputMessages;
NetworkHandler.clientPool = pClientPool;
this.outputQueue = new LinkedBlockingQueue<String>();
}
@Override
public void run() {
this.clientID = "0" + NetworkHandler.clientPool.indexOf(this);
this.threadPool.execute(new NetworkReceiver(this.engineMessages,
this.chatMessages, this.client));
this.threadPool.execute(new NetworkTransmitter(this.outputQueue,
this.client, this.clientID));
while (true) {
NetworkHandler.distributor(); //sortiert die Nachrichten aus OutputMessages in die entsprechende outputQueue
}
}
Zuletzt bearbeitet: