Nuova classe per gestire le connessioni TCP in entrata

Tradotto automaticamente da Deepl

In 4D 20 R8 abbiamo introdotto la classe TCPConnection, che consente di avviare connessioni TCP a server remoti. Con 4D v20 R9, siamo lieti di presentare la classe TCPListener, la chiave per gestire le connessioni TCP in arrivo e costruire un server TCP direttamente in 4D.

Con queste due classi, TCPConnection e TCPListener, avete ora il pieno controllo sulla comunicazione TCP, sia lato client che lato server.

Vediamo come utilizzarle insieme.

HDI TCPConnections

Prima di immergerci in questo post, vi consigliamo di dare un’occhiata al nostro precedente post sulla classe TCPConnection per comprendere le basi su cui stiamo costruendo.

 

Come interagiscono le classi TCPListener e TCPConnection

Definizione della classe Connection

Creeremo una nuova classe chiamata ServerSideConnection, sul modello della classe ConnectionToTheServer usata nell’esempio precedente. Ecco una descrizione dei principali callback da implementare:

Class constructor()

//Callback called when the connection is successfully established
Function onConnection($connection : 4D.TCPConnection; $event : 4D.TCPEvent) 
	ALERT("Connection established") 

//Callback called when the connection is properly closed
Function onShutdown($connection : 4D.TCPConnection; $event : 4D.TCPEvent) 
	ALERT("Connection closed") 

//Callback called when receiving data. The simple servers always send a sentence to show to the user
Function onData($connection : 4D.TCPConnection; $event : 4D.TCPEvent) 
	ALERT(BLOB to text($event.data; UTF8 text without length)) 

//Callback called when the connection is closed unexpectedly
Function onError($connection : 4D.TCPConnection; $event : 4D.TCPEvent) 
	ALERT("Connection error")

Questa classe è una shell semplice che reagisce ai principali eventi TCP.

Impostazione della classe ascoltatore

Ora, creiamo una classe ServerListener per ascoltare su una porta specifica e accettare le connessioni in arrivo:

property listener:4D.TCPListener

shared singleton Class constructor()

//Start listening to the port given as parameter
shared Function startListening($port:integer)
	This.listener:=4D.TCPListener.new($port, This)

//Stop listening
shared Function stopListening()
	This.listener.terminate()

//Callback called on a new incoming connection	
Function onConnection($listener : 4D.TCPListener; $event : 4D.TCPEvent)->$result
	
	ALERT("Listener: onConnection")
	if ($event.IP = "a good IP address")
		$result:=cs.ServerSideConnection.new()
	else
		$result := null
	end if
	
//Callback called when an error prevents listening on the port (in general due to conflict with another application)
Function onError($listener : 4D.TCPListener; $event : 4D.TCPEvent)
	
	ALERT("Listener: onError")

Per avviare l’ascoltatore, utilizzare:

cs.ServerListener.me.startListening($port)

Ogni volta che un client tenta di connettersi, viene attivato il metodo onConnection. Si può restituire un oggetto ServerSideConnection per accettare la connessione o null per rifiutarla. Una volta accettata, vengono attivati i callback TCPConnection corrispondenti, che consentono di gestire la connessione come qualsiasi altro client.

Per interrompere l’ascolto di nuove connessioni, basta chiamare:

cs.ServerListener.me.stopListening()

Nota: le connessioni attive rimangono attive finché non vengono chiuse manualmente.

Struttura di classe unificata = codice semplificato

Uno dei principali vantaggi di questa struttura è che la stessa classe TCPConnection viene utilizzata sia per le connessioni client che per quelle server. Questa simmetria semplifica l’implementazione e favorisce il riutilizzo del codice, poiché il comportamento di entrambe le estremità della connessione può condividere la stessa logica e struttura.

Conclusione

Con l’aggiunta della classe TCPListener in 4D v20 R9, è ora possibile creare robusti server TCP interamente in 4D. Insieme a TCPConnection, i nuovi strumenti offrono un quadro completo per la gestione della comunicazione TCP bidirezionale, in modo pulito, efficiente e con una duplicazione minima del codice.

Se avete domande o commenti, non esitate a farli sul forum di 4D.

Nicolas Brachfogel
- Proprietario del prodotto e sviluppatore senior - Nicolas Brachfogel è entrato in 4D nel 2017 come Senior Developer (4D Server e networking). In qualità di Product Owner per gestire il rilascio di Apple Silicon, si occupa di scrivere le storie degli utenti e di tradurle in specifiche funzionali, nonché di assicurarsi che le implementazioni delle funzionalità soddisfino le esigenze dei clienti. Diplomato all'Institut Supérieur d'Informatique Appliquée (INSIA), Nicolas ha iniziato la sua carriera come sviluppatore di software nel 2001. Dopo diversi anni di codifica in Java e C++, si è specializzato nello sviluppo di client-server per aziende di videogiochi. Come sviluppatore/architetto di server, ha lavorato con successo alle architetture server di molti giochi (Dofus Arena, Drakerz, Trivial Pursuit Go!).