
import java.net.*;
import java.util.*;

/**
 * Der Server nimmt Texte entgegen und sendet diese an alle 
 * verbundenen Clients.
 * @author  Mark Donnermeyer
 */
public class ChatServer extends Thread implements Observer {
    
    Vector handlers = new Vector();
    
    public static void main(String[] args) {
        ChatServer cs = new ChatServer();
        cs.start();
    }
    
    /**
     * In der run() werden neue Verbindungen zu ChatClients
     * aufgebaut
     */
    public void run() {
        ServerSocket socket;
        Socket chat;
        
        System.out.println("Starte ChatServer ...");
        try {
            socket = new ServerSocket(8090);
        }
        catch (Exception e) {
            return;
        }
        
        // Die Hauptroutine des Chat-Servers
        while(true) {
            try {
                // Der Aufruf von accept() blockiert solange, bis sich ein
                // neuer Client mit einem Request an den Server wendet
                chat = socket.accept();
                System.out.println("Client angemeldet ...");
                // Es wird ein neuer Socket-Handler erzeugt, der
                // Texte über die Verbindung versendet und empfängt.
                SocketHandler handler = new SocketHandler(chat);
                handler.addObserver(this);
                Thread thread = new Thread(handler);
                thread.start();
                handlers.add(handler);
            }
            catch (Exception e) { e.printStackTrace(); }
        }
    }
    
    /**
     * Es liegt ein Text eines Clients vor. Der Text wird nun
     * an alle verbundenen Clients verschickt. Wenn ein Client
     * nicht mehr reagiert, dann wird er aus der Liste der
     * Clients gestrichen.
     */
    public synchronized void update(Observable o, Object arg) {
        int i = handlers.size()-1;
        while (i >= 0) {
            SocketHandler tmp = (SocketHandler)handlers.elementAt(i);
            try {
                tmp.write(""+arg);
            } catch (Exception ignore) {
                handlers.removeElement(tmp);
                tmp.stopNow();
                System.out.println("Client abgemeldet ...");
            }
            i--;
        }
    }
}
