Stavo rivedendo le WebSocket ma ho un dubbio su un esempio che ho incontrato.
Supponiamo di avere un applicazione web utilizzabile tramite browser web che permette di avviare l'orologio cliccando su un bottone e di fermarlo cliccando su un altro bottone.
Questo orologio una volta avviato verrà aggiornato ogni secondo in modo da dare l'idea appunto dell'orologio in esecuzione.
L'applicazione è formata da una pagina del Client (praticamente la pagina HTML con codice JavaScript) e una WebSocket server.
Questo è il codice della pagina del client:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Web Socket Clock</title>
<script language="javascript" type="text/javascript">
var websocket;
var last_time;
function init() {
output = document.getElementById("output");
}
function start_clock() {
var wsUri = "ws://localhost:8080/clock-app/clock";
websocket = new WebSocket(wsUri);
websocket.onmessage = function (evt) {
last_time = evt.data;
writeToScreen("<span style='color: blue;'>" + last_time + "</span>");
};
websocket.onerror = function (evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
websocket.close();
};
}
function stop_clock() {
websocket.send("stop");
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
oldChild = output.firstChild;
if ( oldChild == null) {
output.appendChild(pre);
} else {
output.removeChild(oldChild);
output.appendChild(pre);
}
}
window.addEventListener("load", init, false);
</script>
</head>
<body>
<div style="text-align: center;font-family: Arial; font-size: large">
WebSocket Clock
<br></br>
<form action="">
<input
onclick="start_clock()"
title="Press to start the clock on the server"
value="Start"
type="button">
<input
onclick="stop_clock()"
title="Press to stop the clock on the server"
value="Stop"
type="button">
</form>
<div id="output"></div>
</div>
</body>
</html>
Questo è il codice della WebSocket server:
import javax.websocket.OnOpen;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnError;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.IOException;
@ServerEndpoint("/clock")
public class ClockServer {
Thread updateThread;
boolean running = false;
@OnOpen
public void startClock(Session session) {
final Session mySession = session;
this.running = true;
final SimpleDateFormat sdf = new SimpleDateFormat("h:mm:ss a");
this.updateThread = new Thread() {
public void run() {
while (running) {
String dateString = sdf.format(new Date());
try {
mySession.getBasicRemote().sendText(dateString);
sleep(1000);
} catch (IOException | InterruptedException ie) {
running = false;
}
}
}
};
this.updateThread.start();
}
@OnMessage
public String handleMessage(String incomingMessage) {
if ("stop".equals(incomingMessage)) {
this.stopClock();
return "clock stopped";
} else {
return "unknown message: " + incomingMessage;
}
}
@OnError
public void clockError(Throwable t) {
this.stopClock();
}
@OnClose
public void stopClock() {
this.running = false;
this.updateThread = null;
}
}
Vediamo se ho capito il funzionamento di queste WebSocket.
Quando si clicca sul bottone "Start" viene invocata la funzione start_clock() presente sul client che avvia la connessione. Una volta avviata la connessione, poichè sull'endpoint è presente l'annotazione OnOpen viene avviato il metodo startClock() che avvia un thread che permette di restituire al client l'ora (ogni secondo) attraverso un messaggio di tipo stringa.
Questo messaggio di tipo stringa viene intercettato dal codice JavaScript presente sul client grazie all'attributo "onmessage", in realtà è l'evento "evt" che contiene quel messaggio e che viene assegnato a "last_time" che sarà successivamente stampata.
Supponendo che quanto detto è corretto avrei una domanda.
Come fa il client a rimanere in attesa di un messaggio da parte della WebSocket server? Cioè, una volta che viene inviato il primo messaggio con l'orario come fa a ritornare sempre su "onmessage" per elaborare il nuovo messaggio?