Funktionen

Funktionen sind ein Grundbaustein der Programmierung - sie sind eine bequeme und leistungsstarke Möglichkeit, Anweisungen zu gruppieren, die eine Aufgabe ausführen. Sie sind die Schnittstelle zwischen der Citrix ADC-Appliance und dem Erweiterungscode. Für Richtlinien definieren Sie Funktionen zur Richtlinienerweiterung. Für Protokolle implementieren Sie Callback-Funktionen für das Protokollverhalten. Funktionen bestehen aus Funktionsdefinitionen, die angeben, welche Werte in die und aus der Funktion übergeben werden und welche Anweisungen für die Funktion ausgeführt werden, und Funktionsaufrufen, die Funktionen mit bestimmten Eingabedaten ausführen und Ergebnisse aus der Funktion erhalten.

Callback-Funktionen für Protokollverhalten

Das TCP-Clientverhalten besteht aus einer Callback-Funktion (on_data), die TCP-Clientdaten-Stream-Ereignisse verarbeitet. Um Message Based Load Balancing (MBLB) für ein TCP-basiertes Protokoll zu implementieren, können Sie Code für diese Callback-Funktion hinzufügen, um den TCP-Datenstrom vom Client zu verarbeiten und den Byte-Stream in Protokollnachrichten zu analysieren.

Die Callback-Funktionen in einem Verhalten werden mit einem Kontext aufgerufen, bei dem es sich um den Status des Verarbeitungsmoduls handelt. Der Kontext ist die Instanz des Verarbeitungsmoduls. Beispielsweise werden die TCP-Clientverhaltens-Callbacks mit unterschiedlichen Kontexten für verschiedene Client-TCP-Verbindungen aufgerufen.

Zusätzlich zum Kontext können die Verhaltensrückrufe andere Argumente haben. Normalerweise wird der Rest der Argumente als Nutzlast übergeben, was die Sammlung aller Argumente ist. Die Instanzen des programmierbaren Verarbeitungsmoduls können also als eine Kombination aus Instanzstatus und Ereignisrückruffunktionen angesehen werden, dh dem Kontext plus Verhalten. Und der Verkehr fließt durch die Pipeline als Ereignisnutzlast.

Prototyp der TCP-Client-Callback-Funktion:

            Function                client on_data (ctxt, payload)

                                            //.code

            end

Hierbei gilt:

  • ctxt - TCP-Client-Verarbeitungskontext
  • payload — Ereignis-Nutzlast
    • payload.data - TCP-Daten empfangen, verfügbar als Byte-Stream

Funktionen zur Erweiterung von Richtlinien

Da die NetScaler-Richtlinienausdruckssprache typisiert ist, muss die Definition einer Erweiterungsfunktion die Typen ihrer Eingaben und ihren Rückgabewert angeben. Die Lua-Funktionsdefinition wurde um folgende Typen erweitert:

Funktion Selbsttyp: Funktionsname (Parameter1: Parameter1-Typ usw.): Rücksendeanweisungen enden

Hierbei gilt:

Die Typen sind NSTEXT, NSNUM, NSBOOL oder NSDOUBLE. ‘

Selbsttyp ist der Typ des impliziten Selbstparameters, der an die Funktion übergeben wird. Wenn die Erweiterungsfunktion in einem Citrix ADC-Richtlinienausdruck verwendet wird, ist dies der Wert, der durch den Ausdruck links neben der Funktion generiert wird. Eine andere Möglichkeit, dies zu sehen, besteht darin, dass die Funktion diesen Typ in der Citrix ADC Richtliniensprache erweitert.

Die Parametertypen sind die Typen jedes Parameters, der im Erweiterungsfunktionsaufruf im Richtlinienausdruck angegeben ist. Eine Erweiterungsfunktion kann null oder mehr Parameter haben.

Rückgabetyp ist der Typ des Werts, der vom Erweiterungsfunktionsaufruf zurückgegeben wird. Es ist die Eingabe für den Teil des Richtlinienausdrucks, falls vorhanden, rechts von der Funktion oder der Wert des Ausdrucksergebnisses.

Beispiel:

function NSTEXT:COMBINE_HEADERS() : NSTEXT

Verwendung der Erweiterungsfunktion in einem Richtlinienausdruck:

HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1\r\n").COMBINE_HEADERS()

Hier ist der Selbstparameter das Ergebnis von HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1\r\n"), bei dem es sich um einen Textwert handelt. Das Ergebnis des Aufrufs COMBINE_HEADERS () ist Text, und da sich rechts von diesem Aufruf nichts befindet, ist das Ergebnis des gesamten Ausdrucks Text.

Lokale Funktionsdefinition

Neben Erweiterungsfunktionen können in einer Erweiterungsdatei keine globalen Funktionen definiert werden. Lokale Funktionen können jedoch innerhalb von Erweiterungsfunktionen mithilfe der normalen Lua-Funktionsanweisung definiert werden. Dies deklariert den Namen der Funktion und die Namen ihrer Parameter (auch als Argumente bekannt) und gibt wie alle Deklarationen in Lua keine Typen an. Die Syntax dafür lautet:

’ lokale Funktionsname (Parameter1-Name, Parameter2-Name usw.) -Anweisungen enden `

Die Funktions- und Parameternamen sind alle Bezeichner. (Der Funktionsname ist eigentlich eine Variable und die Funktionsanweisung ist eine Abkürzung für lokale Funktionsname = Funktion (Parameter1 usw.), aber Sie müssen diese Feinheit nicht verstehen, um Funktionen zu verwenden.)

Beachten Sie, dass usw. hier für die Fortsetzung des Musters von Parameternamen anstelle des üblichen… verwendet wird. Dies liegt daran, dass… selbst tatsächlich eine variable Parameterliste bedeutet, auf die hier nicht eingegangen wird.

Funktionskörper und Rückkehr

Der Anweisungsblock zwischen den Funktions- und End-Anweisungen ist der Funktionskörper. Im Funktionskörper wirken die Funktionsparameter wie lokale Variablen, wobei Werte, die von den Funktionsaufrufen geliefert werden, wie zuvor beschrieben.

Die Anweisung return liefert Werte, die an den Aufrufer der Funktion zurückgegeben werden. Es muss am Ende eines Blocks erscheinen (in einer Funktion, wenn dann, für Schleife usw.; Es kann in seinem eigenen Block sein, kehren Sie zurück… end). Es kann keine, einen oder mehrere Rückgabewerte angeben:

’ return — gibt einen Rückgabeausdruck zurück — ein Rückgabewert gibt Ausdruck1, Ausdruck2,… — mehrere Rückgabewerte ‘

Beispiele:

’ lokale Funktion fsum (a) lokale Summe = 0 für i = 1, #a do sum = Summe + ein[i] Ende der

Rückgabesumme

Lokale Funktion fsum_and_average (a) lokale Summe = 0 für i = 1, #a do sum = Summe + eine[i]

 Endrückgabesumme, sum/ #a end `

Funktion ruft

Ein Funktionsaufruf führt den Rumpf einer Funktion aus, liefert Werte für ihre Parameter und empfängt Ergebnisse. Die Syntax für einen Funktionsaufruf ist Funktionsname (Ausdruck1, Ausdruck2 usw.), wobei die Funktionsparameter auf die entsprechenden Ausdrücke gesetzt werden. Die Anzahl der Ausdrücke und Parameter muss nicht gleich sein. Wenn es weniger Ausdrücke als Parameter gibt, werden die verbleibenden Parameter auf Null gesetzt. So können Sie am Ende des Aufrufs einen oder mehrere Parameter optional machen, und Ihre Funktion kann überprüfen, ob sie angegeben sind, indem sie prüft, ob sie nicht Null sind. Ein üblicher Weg, dies zu tun, ist mit der Operation oder:

’ Funktion f (p1, p2) — p2 ist optional p2 = p2 oder 0 — wenn p2 gleich Null ist, auf einen Standardwert von 0 gesetzt . ende ‘

Wenn es mehr Ausdrücke als Parameter gibt, werden die verbleibenden Ausdruckswerte ignoriert.

Wie bereits erwähnt, können Funktionen mehrere Werte zurückgeben. Diese Rückgaben können in einer Anweisung mit mehreren Zuweisungen verwendet werden. Beispiel:

’ lokal my_array = {1, 2, 3, 4} lokal my_sum, my_ave = sum_and_average (mein_array) ‘

Iterator-Funktionen und generische for-Schleifen

Jetzt, da wir Funktionen eingeführt haben, können wir über generische for-Schleifen sprechen. Die Syntax für die generische for-Schleife (mit einer Variablen) lautet:

’ für Variable im Iterator (Parameter1, Parameter2 usw.) tun Anweisungen im Körperende der for-Schleife ‘

Wobei iterator () eine Funktion mit null oder mehr Parametern ist, die bei jeder Iteration des Schleifenkörpers einen Wert für eine Variable liefern. Die Iterator-Funktion verfolgt mithilfe einer Technik namens Closure, wo sie sich in der Iteration befindet, über die Sie sich hier keine Sorgen machen müssen. Es signalisiert das Ende der Iteration, indem es Null zurückgibt. Iterator-Funktionen können mehr als einen Wert zur Verwendung in mehreren Zuweisungen zurückgeben.

Das Schreiben einer Iterator-Funktion geht über den Rahmen dieses Papiers hinaus, aber es gibt nur wenige nützliche integrierte Iteratoren, die das Konzept veranschaulichen. Einer ist der Iterator pairs (), der die Einträge in einer Tabelle durchläuft und zwei Werte zurückgibt, den Schlüssel und den Wert des nächsten Eintrags.

Beispiel:

’ lokal t = {k1 = “v1”, k2 = “v2”, k3 = “v3”} lokal a = {} — array zum akkumulieren von Schlüssel-Wert-Paaren lokal n = 0 — Anzahl der Schlüssel-Wert-Paare für Schlüssel, Wert paarweise (t) tun n = n + 1 a[n] = Schlüssel.. “= “.. Wert - füge Schlüssel-Wert-Paar zum Array-Ende hinzu local s = table.concat (a, “;”) - verkette alle Schlüssel-Wert-Paare zu einer Zeichenfolge ‘

Ein weiterer nützlicher Iterator ist die string.gmatch () Funktion, die im folgenden COMBINE_HEADERS () Beispiel verwendet wird.

Funktionen