Ve verzi 4D 20 R8 jsme zavedli třídu TCPConnection, která umožňuje navazovat spojení TCP se vzdálenými servery. Ve verzi 4D v20 R9 vám s potěšením přinášíme třídu TCPListener – váš klíč k obsluze příchozích spojení TCP a k sestavení serveru TCP přímo ve 4D.
S těmito dvěma třídami – TCPConnection a TCPListener – máte nyní plnou kontrolu nad komunikací TCP jak na straně klienta, tak na straně serveru.
Projdeme si, jak je společně používat.
Než se ponoříte do tohoto příspěvku, důrazně doporučujeme přečíst si náš předchozí příspěvek na blogu o třídě TCPConnection, abyste pochopili základy, na kterých stavíme.
Jak spolu třídy TCPListener a TCPConnection spolupracují
Definice třídy Připojení
Vytvoříme novou třídu s názvem ServerSideConnection po vzoru třídy ConnectionToTheServer použité v předchozím příkladu. Zde je rozpis klíčových zpětných volání, která budete implementovat:
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")
Tato třída je přímočará schránka, která reaguje na klíčové události TCP.
Nastavení třídy Listener
Nyní vytvoříme třídu ServerListener, která bude naslouchat na určitém portu a přijímat příchozí spojení:
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")
Pro spuštění posluchače použijte následující příkaz:
cs.ServerListener.me.startListening($port)
Pokaždé, když se klient pokusí připojit, spustí se metoda onConnection. Můžete vrátit objekt ServerSideConnection, abyste připojení přijali – nebo vrátit null, abyste ho odmítli. Po přijetí se spustí odpovídající zpětná volání TCPConnection, která vám umožní zpracovávat připojení jako u jakéhokoli jiného klienta.
Chcete-li přestat naslouchat novým spojením, stačí zavolat:
cs.ServerListener.me.stopListening()
Poznámka: Aktivní spojení zůstanou zachována, dokud je ručně neuzavřete.
Jednotná struktura třídy = zjednodušený kód
Hlavní výhodou této konstrukce je, že pro klientská i serverová připojení se používá stejná třída TCPConnection. Tato symetrie zjednodušuje implementaci a podporuje opakované použití kódu, protože chování pro oba konce spojení může sdílet stejnou logiku a strukturu.
Závěr
Díky přidání třídy TCPListener v 4D v20 R9 můžete nyní vytvářet robustní servery TCP zcela v prostředí 4D. Ve spojení s TCPConnection vám nové nástroje poskytují kompletní rámec pro obsluhu obousměrné komunikace TCP – čistě, efektivně a s minimální duplikací kódu.
Máte-li jakékoli dotazy nebo připomínky, neváhejte je vznést na fóru 4D.