In der Python-Webentwicklung kann das Serverprogramm in zwei Teile unterteilt werden:
Serverprogramm (wird zum Empfangen und Organisieren von vom Client gesendeten Anforderungen verwendet)
Anwendungsprogramm ( Verarbeitung von Anforderungen, die vom Serverprogramm übergeben werden)
Bei der Entwicklung von Anwendungen kapseln wir häufig verwendete Funktionen in verschiedene Frameworks wie Flask, Django und Tornado (die Verwendung eines bestimmten Frameworks für die Webentwicklung entspricht der Entwicklung von Diensten (Endanwendung, Verarbeitung der Hintergrundlogik)
Das Serverprogramm und das Anwendungsprogramm arbeiten jedoch zusammen, um den Benutzern Dienste bereitzustellen, und unterschiedliche Anwendungen (unterschiedliche Frameworks) haben unterschiedliche Funktionen und Funktionen. Zu diesem Zeitpunkt benötigen wir einen Standard, damit sowohl Serverprogramme als auch Anwendungen diesen Standard unterstützen können.
WSGI: wsgi ist ein Standard für die Python-Webentwicklung, ähnlich einem Protokoll. Es handelt sich um eine Konvention zwischen dem Serverprogramm und dem Anwendungsprogramm, die die von beiden verwendeten Schnittstellen und Funktionen festlegt, damit die beiden miteinander zusammenarbeiten können
Teil der Bestimmungen der WSGI-Anwendung
Die Anwendung ist ein aufrufbares Objekt
Es gibt drei Arten von aufrufbaren Objekten:
eine Funktion
eine Klasse, die die Methode __call__() implementieren muss
ein Klassenbeispiel
Dieses Objekt empfängt zwei Parameter
Aus dem Quellcode können wir erkennen, dass diese beiden Parameter environ und start_response sind. Nehmen wir das aufrufbare Objekt als Klasse ein Beispiel:
Klassenanwendung:
def __call__(self, environ, start_response):
pass
Das aufrufbare Objekt muss einen iterierbaren Wert zurückgeben. Nehmen Sie als Beispiel das aufrufbare Objekt als Klasse:
Klassenanwendung:
def __call__(self, environ, start_response):
return [xxx]
WSGI server Einige Bestimmungen des Programms
Das Serverprogramm muss die Anwendung aufrufen
def run(application): #Das Serverprogramm ruft die Anwendung auf
environ = {} #Parameter festlegen
def start_response(xxx): #Parameter festlegen
pass
result = application(environ, start_response) #Rufen Sie die __call__-Funktion der Anwendung auf (hier ist die Anwendung eine Klasse)
def write (Daten):
PASS
DEF DATA in Result:#))
Write (data)
Das Serverprogramm führt hauptsächlich Folgendes aus:
1. Stellen Sie die für die Anwendung erforderlichen Parameter ein 🎜> 2. Rufen Sie die Anwendung auf
3. Iterieren Sie das Rückgabeergebnis der Anwendung und übergeben Sie es an den Client
Für das Anwendungsprogramm ist die Middleware das Serverprogramm. Die Middleware muss als Serverprogramm getarnt sein.
DEF URLROUTING (URL_APP_MAPPING):
DEF MIDWARE_APP (ENVIRON, Start_Response): #Funktion kann aufgerufen werden, einschließlich 2 Parametern, zurück zur Iteration value
URL = ENVINF O ']
APP = url_app_mapping[url] #Rufen Sie die der URL entsprechende Anwendung ab
result = app(environ, start_response) #Rufen Sie die Anwendung auf
Ergebnis zurückgeben
return midware_app
Die Funktion midware_app ist Middleware:
Andererseits ist die Funktion midware_app ein aufrufbares Objekt, das zwei Parameter empfängt, und das aufrufbare Objekt gibt einen iterierbaren Wert zurück. Für das Serverprogramm handelt es sich also um eine Anwendung.
Die Logik des Schreibens von Middleware (Middleware):
2. Middleware muss als Serverprogramm getarnt sein –> WSGI-Serverprogrammanforderungen –>
Wir müssen die variable Umgebung verstehen. In WSGI benötigt die Anwendung zwei Parameter: environ und start_response. Diese beiden Parameter müssen festgelegt werden, bevor das Serverprogramm die Anwendung aufruft. Unter diesen ist start_response normalerweise eine aufrufbare Methode und environ ist ein Wörterbuch, das in CGI definiert ist. Die Definition von environ finden Sie im CGI-Dokument „The Common Gateway Interface Specification“.
Das Folgende sind die Parameter in der Umgebung:
AUTH_TYPE
CONTENT_LENGTH #Der Content-Length-Teil der HTTP-Anfrage
CONTENT_TYPE #Der Content-Tpye-Teil der HTTP-Anfrage
GATEWAY_INTERFACE
HTTP_* #Enthält eine Reihe von Variablen, z. B. HTTP_HOST, HTTP_ACCEPT usw.
PATH_INFO #Der verbleibende Teil des URL-Pfads mit Ausnahme des Anfangsteils wird verwendet, um das entsprechende Anwendungsobjekt zu finden der Stammpfad, dieser Wert ist leer String
PATH_TRANSLATED
QUERY_STRING #URL-Pfad? Der folgende Teil
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_USER
REQUEST_METHOD #HTTP-Anforderungsmethode, z. B. „GET“, „POST“
SCRipT_NAME #Die Anwendung, die dem Anfangsteil von entspricht der URL-Pfad Programmobjekt, wenn das Anwendungsobjekt dem Stammverzeichnis des Servers entspricht, dann kann dieser Wert eine leere Zeichenfolge sein
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL #vom Client angefordertes Protokoll (HTTP/1.1 HTTP/ 1.0)
SERVER_SOFTWARE
Zum Beispiel: http://localhost:5000/aaa?666, der Variablenwert ist:
REQUEST_METHOD='GET'
SCRIPT_NAME =''
SERVER_NAME= 'localhost'
SERVER_PORT='5000'
PATH_INFO='/aaa'
QUERY_STRING='666'
SERVER_PROTOCOL='HTTP/1.1'
CONTENT_TYPE ='text/plain'
CONTEN_LENGTH=''
HTTP_HOST = 'localhost:8000'
HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9, image/webp,*/*; q=0.8'
HTTP_ACCEPT_ENCODING = 'gzip,deflate,sdch'
HTTP_ACCEPT_LANGUAGE = 'en-US,en;q=0.8,zh;q=0.6,zh-CN; q=0.4,zh-TW; q=0.2'
HTTP_CONNECTION = 'keep-alive'
HTTP_USER_AGENT = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/32.0. 1700,77 Safari/537,36'
Für die Funktion start_response():
start_response ist der Anfang der HTTP-Antwort, ihre Form ist: start_response(status, Response_headers, exc_info=None)
Status stellt den HTTP-Statuscode dar, z. B. 200 OK
response_headers ist eine Liste und das Listenelement ist ein Tupel: (header_name, header_value)
exc_info ist ein optionaler Parameter, wenn während der Verarbeitung der Anfrage ein Fehler auftritt , dieser Parameter wird gesetzt und gleichzeitig wird start_response aufgerufen
Geben Sie eins Ich habe das Beispiel im offiziellen Werkzeug-Dokument zur Analyse leicht verbessert (es wird empfohlen, diesen Abschnitt nach dem Lesen der SharedDataMiddleware-Klasse im zweiten Teil zu lesen von wsgi.py):
class Shortly(object):
def __init__(self, config):
self.redis = redis.Redis(config['redis_host'], config['redis_port'])
def packet_request(self, request):
return Response('Hello World!') #Initialize Response class
def wsgi_app(self, environ, start_response):
request = Request(environ)
Response = self.dispatch_re quest(request ) #Der Antworttyp ist Antwortklasse
print('%%%%%%%%%%% %%%%%%%%%%%%%')
return Response(environ , start_response) #Responses __call__-Funktion ist die Anwendung und gibt das Iterationsobjekt zurück
def __call__(self, environ, start_response):
print(self.wsgi_app)
print('erghrgheoghegoierge' )
return self. , redis_port=6379, with_static=True):
app = Shortly({
'redis_host': ' redis_host,
'redis_port': redis_port
})
if with_static:
print('yes')
app.wsgi_app = SharedDataMiddleware(app .wsgi_app, { '/Static': OS.Path.join (os.Path.diRName (__file__), 'STATIC')
})
Drucken ('333333333333333')
Rückgabe
#Open Local server
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = create_app() #Erstellen Sie eine Instanz der Anwendung
run_simple('127.0.0.1', 5000, app , use_debugger=True, use_reloader=True)
Wir schauen uns den Quellcode von Response an (Response erbt BaseResponse, schauen Sie sich einfach den Quellcode von BaseResponse an) und wir können wissen: Der von der Funktion „dispatch_request()“ zurückgegebene Wert ist der Konstruktor von Request, also eine Antwort Die Klasse wird zurückgegeben, in der Funktion wsgi_app() ist der Werttyp der Anforderung Response, sodass der Rückgabewert von wsgi_app(), Response(environ, start_response), tatsächlich die Funktion __call__() der Response-Klasse aufruft.
Nachdem wir uns den Quellcode angesehen haben, können wir feststellen, dass __call__() eine WSGI-Anwendung ist!
Beim Ausführen dieses Programms:
22222222222222222
Ja
33333333333333333
* Läuft auf http://127.0.0.1:5000/ (Drücken Sie STRG+C zum Beenden)
* Neustart mit Statistik
22222222222222222
ja
33333333333333333
Machen wir uns keine Sorgen darüber, warum es zweimal gelesen wurde.
Wenn wir diese Webseite öffnen, lautet die Ausgabe der Konsole:
erghrgheoghegoierge
%%%%%%%%%%%%%%%%%%%%%%% #Zeigt an, dass der Inhalt in der ursprünglichen wsgi_app-Funktion ausgeführt wird!
127.0.0.1 - - [22/Mai/2015 21:01:25] "GET/HTTP/1.1" 200 -
Wie Sie sehen können, in diesem Fall app.wsgi_app Diese Methode ist zu einer Instanz der SharedDataMiddleware-Klasse geworden. Ich frage mich, warum wsgi_pp den Inhalt in der ursprünglichen wsgi_app immer noch ausführt, nachdem der Server environ und start_response an die App übergeben hat.
Wenn wir auf die Hostadresse zugreifen, akzeptiert das Serverprogramm die Benutzeranforderung und übergibt dann environ und start_response an die Anwendungs-App. Die App führt die Funktion __call__ aus, in der die Funktion app.wsgi_app ausgeführt wird. Dann führt wsgi_app die __call__()-Funktion von ShareDataMiddleware aus
Hier müssen wir uns den Quellcode von __call__() der SharedDataMiddleware-Klasse ansehen. Wenn wir uns den Quellcode ansehen, können wir feststellen, dass return self.app(environ, start_response) ausgeführt wird, da der Benutzer keine statische Datei angefordert hat. In diesem Beispiel können wir sehen, dass wir in create_app() die ShareDataMiddleware-Anwendung verwenden Definiert ist app.wsgi_app, also wird hier die ursprüngliche wsgi_app-Funktion zurückgegeben! Daher wird natürlich die ursprüngliche Funktion ausgeführt~
Gleichzeitig können wir auch eine Datei im statischen Ordner ablegen und dann versuchen, darauf zuzugreifen: 127.0.0.1/static/filename, und Sie können die Datei jetzt sehen !
Anhand dieses Beispiels können wir die Rolle der Middleware besser verstehen:
Middleware befindet sich zwischen dem Serverprogramm und dem Anwendungsprogramm. Sie empfängt Nachrichten vom Server (Umgebung und
start_response). ) und bestimmte Verarbeitungen durchführen und dann die Teile, die von der Anwendung verarbeitet werden müssen, zur Verarbeitung an die Anwendung übergeben
Darüber hinaus muss das Serverprogramm auch WSGI-bezogene Variablen definieren:
wsgi.version
Der Wert hat die Form (1, 0) und steht für WSGI-Version 1.0 Der Textteil der HTTP-Anfrage kann hier gelesen werden. multithread
Wenn das Anwendungsobjekt von einem anderen Thread im selben Prozess verwendet werden kann. Ein Thread ruft gleichzeitig auf, dieser Wert ist True
wsgi.multiprocess
Wenn das Anwendungsobjekt von einem anderen Prozess aufgerufen werden kann Gleichzeitig ist dieser Wert True
wsgi.run_once
Wenn der Server möchte, dass das Anwendungsobjekt gleichzeitig aufgerufen wird Es wird nur einmal in dem Prozess aufgerufen, der es enthält, dann ist der Wert True
Das Obige ist das, was WSGI versteht. Weitere verwandte Artikel finden Sie auf der chinesischen PHP-Website (www.php.cn)!