Ho una domanda generale sulla progettazione di un'applicazione di chat server multi-thread scritta in Java. Al momento ho la seguente struttura:
-
ConnectionController
class che gestisce lo stream di socket I / O di ogni client connesso -
ConnectionHandler
class che contiene un oggetto di classeConnectionController
ed è responsabile dell'autenticazione del client e della messaggistica -
ServerRuntime
class che accetta nuove connessioni e contiene l'oggettoServerSocket
Ogni client dovrebbe essere registrato con un nome utente univoco! Per garantire il nome utente univoco, la classe ServerRuntime
deve contenere una raccolta con i nomi utente già registrati. La classe fornirà un metodo per allocare un nuovo nome utente.
class ServerRuntime
{
Collection registeredUsernames;
public registerNewUsername(String username)
{
// Check if username exists
}
}
La mia idea attuale è che ogni ConnectionHandler
chiama quel metodo per allocare un nome utente per il client gestito. Domanda: come dovrei progettare la classe ServerRuntime
? Vedo due opzioni come una classe singleton o un argomento di riferimento dato a ciascun oggetto ConnectionHandler
. Quale design è suggerito?
EDIT qui è la struttura di base della classe ServerRuntime
:
class ServerRuntime implements Runnable
{
private Set <String> nameSet; // Collection which stores usernames
private List <ConnectionController> controllerList;
@Override public void run()
{
try(ServerSocket socket = new ServerSocket(this.port, this.backlog, this.host))
{
while (true)
{
ConnectionHandler handler = new ConnectionHandler(new ConnectionController(socket.accept()));
this.clientPool.execute(handler);
}
}
catch(IOException exc)
{
RuntimeLogger.getInstance().getLogger().warning(exc.getMessage());
exc.printStackTrace();
}
}
public void allocateUserName(String name) { ... }
public void freeUserName(String name) { ... }
public void registerController(ConnectionController controller) { ... }
public void deleteController(ConnectionController controller) { ... }
public void broadcastMessage(String message)
{
for(ClientController controller : this.controllerList)
{
controller.send(message);
}
}
}
La classe è responsabile della gestione delle nuove connessioni client e della trasmissione di messaggi. Se un cliente desidera trasmettere un messaggio, vengono richiamati i metodi di questa classe! Come già triste, questa classe è anche responsabile di garantire nomi univoci e di memorizzare tutti i controller per i client connessi. Ma tutte le altre azioni come l'I / O essenziale per un socket client o il processo di autenticazione sono gestite da un'altra classe.