In questo articolo, vedremo come implementare una semplice Chat (comunque abbastanza completa nelle sue funzionalità) per mezzo di un Applet. In particolare, utilizzeremo un JApplet
realizzato con la versione 1.5.0_06 di J2SE.
Prerequisiti
Per avere una idea chiara della struttura del programma e delle classi utilizzate, è bene avere chiari i seguenti concetti:
- Swing e Componenti GUI
- Socket
- Thread
Obiettivo
La nostra chat dovrà essere in grado di:
- Mantenere una lista degli utenti connessi visibile a tutti i partecipanti in linea
- Consentire l'accesso ad un utente previa scelta di un nickname
- Controllare che il nickname scelto da un utente non sia già in uso
- Inviare un messaggio informativo a tutti gli utenti quando entra in chat un nuovo partecipante
- Inviare un messaggio informativo a tutti gli utenti quando un partecipante esce dalla chat
- Notificare tutti gli utenti connessi all'inserimento di un nuovo messaggio immesso da un qualsivoglia partecipante
Le classi
Le classi che realizzeremo per il nostro Applet sono:
- JChat
- ParallelClient (una inner class all'interno della classe JChat)
- JChatClient
- JChatServer
- ParallelServer (una inner class all'interno della classe JChatServer)
- JChatServerRunner
Prima di esaminare il codice che le implementa, analizziamo il loro ruolo e comportamento in maniera generale.
La classe JChat
rappresenta l'applet che viene eseguito all'interno dei browser degli utenti. In particolare, si è scelto di implementare un JApplet
, ovvero un applet costruito ereditando proprio dalla classe JApplet
di Swing. All'interno di JChat
viene, pertanto, costruita e gestita l'interfaccia utente ed istanziato un client di tipo JChatClient
che si occuperà di gestire il dialogo con il server (JChatServer
).
La classe ParallelClient
, come detto, è una classe interna a JChat
. Essa viene utilizzata per l'implementazione di un thread che consente al singolo client di rimanere in ascolto sui messaggi del server finchè l'utente non si disconnette dalla chat.
La classe JChatClient
gestisce la comunicazione con il Server attraverso l'implementazione di un oggetto di tipo Socket
.
La classe JChatServer
rappresenta il server della Chat
, sul quale giungono i messaggi di tutti gli utenti. A tale classe è delegato il compito di smistare a tutti i client connessi i messaggi giunti dai vari partecipanti alla chat.
La classe JChatServerRunner
è una semplice classe il cui compito è quello di mandare in esecuzione il server.
Il codice
Vediamo, innanzitutto, il codice della classe JChat
e della classe ParallelClient
, inglobata al suo interno.
Osservando il codice possiamo riassumere i compiti svolti dalla classe JChat
nel modo seguente:
- Costruisce l'interfaccia grafica del JApplet, utilizzando alcuni componenti Swing. Inoltre, gestisce le funzioni init() e destroy() dell'Applet stesso.
- Gestisce gli eventi derivanti dalla pressione dei pulsanti "Entra in Chat" (che dopo la connessione diviene "Esci") e "Invia Messaggio"
- Crea un oggetto di classe JChatClient, che si occuperà della comunicazione via Socket con il Server.
- Crea un oggetto di classe ParallelClient il cui metodo run() gestisce la comunicazione con il Server in modo indipendente fino a quando l'utente non decide di disconnettersi dalla chat.
È importante sottolineare il fatto che la comunicazione tra client e server dovrà essere supportata da un "linguaggio comune" che consenta uno scambio di informazioni chiaro tra i due componenti. A tale scopo, si è previsto che :
- Il client che intenda entrare in chat invierà un messaggio al server del tipo:
~NickName
, doveNickName
sarà il nick scelto dall'utente. - Un client già connesso alla chat, invierà al server, una stringa composta dal nick seguito dal carattere ':' e dal messaggio inserito nel text field indicato dalla label: "Il tuo Messaggio".
- Un client che intenda disconnettersi dalla chat invierà un messaggio al server del tipo: ^NickName, con NickName uguale al nick scelto all'inizio dall'utente.
- Il server, potrà rispondere ai client in uno dei seguenti modi:
NOGOODUSER
. Questo messaggio verrà inviato al client che ha tentato di entrare in chat con un nick già utilizzato da qualche partecipante.OKNEWUSER~NickName1~NickName2...
Questo messaggio verrà inviato al client che si vuole connettere alla chat, nel caso in cui la sua richiesta sia andata a buon fine. Dopo il primo carattere '~' segue la lista degli utenti già connessi, anch'essi separati dallo stesso carattere. Tale lista va a riempire la lista degli utenti(JList lstUsers
).NEWUSERNickName
. Il client riceve tale messaggio quando in chat è entrato un nuovo utente, il cui nick si trova subito dopo la sottostringa iniziale "NEWUSER". La JList lstUsers aggiunge tale nick in coda.REMOVEUSERNickName
. Il client riceve tale messaggio quando un altro utente si è disconnesso dalla chat. Il nick (seguente la sottostringa iniziale "REMOVEUSER") viene, quindi, rimosso dalla JList lstUser.
Attraverso il codice della classe JChatServer
e quindi della classe ParallelServer
, inglobata al suo interno, è possibile osservare come vengono implementate tali funzionalità. Si noti, anche in questo caso, l'uso dei thread (uno per ogni client) per restare in ascolto dei messaggi in arrivo.
La classe JChatClient
è quella che si occupa di aprire una comunicazione via Socket con il Server, tramite l'indirizzo di quest'ultimo e la porta 7777
su cui il server è in ascolto (naturalmente non è obbligatorio utilizzare questa porta).