La caratteristica più interessante del framework Vert.x è che fornisce funzionalità che consentono di realizzare server TCP, HTTP, WebSocket, etc., in modo semplice e veloce. Dopo aver introdotto il framework negli articoli Primi Passi con Vert.x (parte 1) e Primi Passi con Vert.x (parte 2), continuiamo la serie mostrando come sia possibile implementare un server e client TCP.
Creiamo quindi un progetto Maven ed inseriamo nel pom.xml
la dipendenza al framework:
1 2 3 4 5 |
<dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>3.5.4</version> </dependency> |
Implementazione del Server TCP
Creiamo nel progetto la classe MainTcpServer
ed il relativo metodo main()
. Al suo interno eseguiremo tutte le azioni necessarie per l’implementazione e l’avvio del server TCP, che possono essere così riepilogate:
- Creazione di un oggetto di tipo
NetServer
(che rappresenta un server TCP) eventualmente configurandolo con differenti opzioni. - Definizione di un handler che viene invocato dal server ogni volta che una nuova connessione viene aperta da un client.
- Avvio del server TCP.
Procediamo con l’esecuzione del primo step e generiamo un oggetto di tipo NetServer configurandolo in modo da metterlo in ascolto sulla porta 9090
dell’host localhost
:
1 2 3 4 5 6 7 8 9 10 |
public static void main(String[] args) { Vertx vertx = Vertx.vertx(); NetServerOptions options = new NetServerOptions() .setPort(9090) .setHost("localhost"); NetServer server = vertx.createNetServer( options ); } |
Successivamente definiamo un handler che dovrà gestire la comunicazione nel momento in cui una nuova connessione viene aperta. A tale scopo la classe NetServer
fornisce il metodo connectHandler()
:
1 2 3 4 5 |
server.connectHandler( socket -> { socket.handler(buffer -> { System.out.println( buffer.toString() ); }); }); |
L’handler riceve in input on oggetto di tipo NetSocket
che consente di leggere e scrivere dati nella socket e di eseguire altre operazioni come la chiusura della socket stessa. Nello stesso modo per leggere i dati dalla socket è possibile registrare un handler attraverso il metodo handler()
dell’oggetto NetSocket
, che riceverà in input un oggetto di tipo Buffer
contenente la sequenza di byte di input. Nel nostro esempio si è deciso di stampare su console il contenuto del buffer attraverso il metodo toString()
.
Infine dobbiamo avviare il server TCP invocando il metodo listen()
. Ancora una volta è possibile definire un handler per determinare l’esito dell’operazione, che altrimenti non ci sarebbe noto.
1 2 3 4 5 6 7 |
server.listen( res -> { if (res.succeeded()) { System.out.println("Server is now listening!"); } else { System.out.println("Failed to bind!"); } }); |
Test di Connessione
Facciamo un test eseguendo il progetto e successivamente inserendo in un browser l’url http://localhost:9090. Sulla console troveremo stampata la richiesta standard inviata dal browser:
1 2 3 4 5 6 7 8 9 |
Server is now listening! GET / HTTP/1.1 Host: localhost:9090 Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7 |
Implementazione del Client TCP
Creiamo la classe MainTcpClient
ed il relativo metodo main()
. Al suo interno utilizzeremo il metodo createNetClient()
dell’oggetto Vertx
per istanziare un oggetto NetClient
che rappresenta un client TCP.
1 2 3 4 5 6 7 8 9 10 11 |
public static void main(String[] args) { Vertx vertx = Vertx.vertx(); NetClientOptions options = new NetClientOptions() .setConnectTimeout(10000) .setReconnectAttempts(10) .setReconnectInterval(500); NetClient client = vertx.createNetClient(options); } |
- il timeout di connessione a 1 secondo (1000ms);
- il numero di tentativi di connessione (10);
- l’intervallo tra un tentativo di connessione ed il successivo (500ms).
Per l’apertura della connessione verso il server è possibile utilizzare il metodo connect()
specificando l’host, la porta e naturalmente l’handler che gestirà il risultato del tentativo di connessione.
1 2 3 4 5 6 7 8 9 10 |
client.connect(9090, "localhost", res -> { if (res.succeeded()) { System.out.println("Connected!"); NetSocket socket = res.result(); socket.write( "Hi I'm the TCP client." ); } else { System.out.println("Failed to connect: " + res.cause().getMessage()); } }); |
In caso di connessione avvenuta con successo il risulta dell’operazione conterrà un oggetto NetSocket
attraverso il quale sarà possibile comunicare col server. Una volta avviate le due classi MainTcpServer
e MainTcpClient
sulla console del server verrà stampato:
1 2 |
Server is now listening! Hi I'm the TCP client. |
Codice Sorgente
Il codice sorgente con tutti gli esempi mostrati è scaricabile qui vertx-tcp.