Java consente utilizzare i WebSocket in maniera piuttosto semplice, la cosa comoda rispetto alle solite (storiche) connessioni via socket è che il multithreading viene gestito dal sistema e non dal programmatore.
Quello che segue sotto è un programma minimale che invia un messaggio e riceve una risposta via WebSocket, i System.out.println sparsi nel programma sono ovviamente inutili, servono soltanto per stampare nella console dei messaggi informativi.
All'interno del programma ci sono dei link alla documentazione standard di Java, non è facilissima da leggere ma è chiara, solitamente dettagliata, ben scritta, ben presentata e... dopo tutto l'ha scritta chi ha scritto i programmi che fanno parte della libreria.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.net.http.WebSocket.Builder;
import java.net.http.WebSocket.Listener;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
public class MessaggiPesantiRicezione {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// creao un nuovo oggetto che è in grado di comunicare via HTTP
// una cosa simile a Button x = new Button();
HttpClient httpClient = HttpClient.newHttpClient();
// creo un nuovo oggetto che userò poi per aver un websocket
Builder webSocketBuilder = httpClient.newWebSocketBuilder();
// per quanto ci riguarda è una solita URL (le URI sono un superinsieme delle URL)
URI uri = URI.create("ws://localhost:8080/serverchat/lungo");
// creo l'ascoltatore, viene chiamato quando ci sono informazioni da elaborare
// ha più metodi dei due scritti qui sotto
Listener listener = new Listener() {
// uno StringBuffer è una specie di "stringa dinamica" a cui posso aggiungere caratteri
StringBuffer buffer = new StringBuffer();
// quando arriva del testo viene chiamato questo metodo
// CharSequence rappresenta una sequenza di caratteri,
// ad esempio String è una sottoclasse di Charsequence
@Override
public CompletionStage<Void> onText(WebSocket webSocket, CharSequence data, boolean last) {
// dichiaro che aspetto un ulteriore messaggio, se non lo faccio chiude il socket dopo il primo
webSocket.request(1);
// accodo i caratteri ricevutio al mio buffer
buffer.append(data);
if( last ) {
// se è l'ultimo blocco di dati stampo sulla console il messaggio intero
System.out.println("messaggio completato");
String messaggioIntero = buffer.toString();
System.out.println( messaggioIntero );
} else {
// è un pezzo di un messaggio più lungo...
System.out.println("arrivati "+(data.length())+"caratteri, ne attendo di altri");
}
// dichiaro a chi mi ha chiamato di aver completato il mio lavoro su "Charsequence data"
return null;
}
// in caso di problemi viene chiamato questo metodo
@Override
public void onError(WebSocket webSocket, Throwable errore) {
errore.printStackTrace();
}
};
// creazione del websocket
WebSocket webSocket = webSocketBuilder.buildAsync(uri, listener).get();
// invio il messaggio
webSocket.sendText("ciao", true);
// NB: se qui il programma termina non fa in tempo a ricevere nulla!
// nei 3 secondi che questo Thread (quello principale del programma) dorme
// si spera che arrivino i dati dal server
System.out.println("dormo 3 secondi");
Thread.sleep(3000);
System.out.println("termino il programma fine.");
}
}