Heim  >  Artikel  >  Backend-Entwicklung  >  So verwenden Sie asynchrone, nicht blockierende Python-Streams

So verwenden Sie asynchrone, nicht blockierende Python-Streams

王林
王林nach vorne
2023-05-21 22:02:081382Durchsuche

1. Asynchrone Streams

Einer der Hauptvorteile von Asyncio ist die Möglichkeit, nicht blockierende Streams zu verwenden.

Asyncio bietet nicht blockierende I/O-Socket-Programmierung. Dies wird über Streams bereitgestellt.

Kann Sockets öffnen, die den Zugriff auf Stream-Autoren und Stream-Autoren ermöglichen. Verwenden Sie Coroutinen, um Daten aus dem Stream zu schreiben und zu lesen und bei Bedarf anzuhalten. Sobald der Vorgang abgeschlossen ist, kann der Socket geschlossen werden.

Die asynchrone Streaming-Funktionalität ist auf niedrigem Niveau, was bedeutet, dass alle erforderlichen Protokolle manuell implementiert werden müssen.

Dies kann gängige Webprotokolle umfassen wie:

  • HTTP oder HTTPS

    #🎜 🎜#
  • #🎜 🎜#SMTP für die Interaktion mit E-Mail-Servern
  • FTP für die Interaktion mit Dateiservern.
  • Diese Streams können auch zum Erstellen von Servern zur Bearbeitung von Anfragen mithilfe von Standardprotokollen oder zum Entwickeln eigener anwendungsspezifischer Protokolle verwendet werden.

Da wir nun wissen, was asynchrone Streams sind, sehen wir uns an, wie man sie verwendet.

2. So öffnen Sie eine Verbindung

Sie können die Funktion asyncio.open_connection() verwenden, um eine asynchrone TCP-Client-Socket-Verbindung zu öffnen.

Dies ist eine Coroutine, die warten und zurückkehren muss, sobald die Socket-Verbindung geöffnet wird.

Diese Funktion gibt StreamReader- und StreamWriter-Objekte für die Interaktion mit dem Socket zurück.

...
# open a connection
reader, writer = await asyncio.open_connection(...)

Es gibt mehrere Parameter, die zum Konfigurieren der Socket-Verbindung in der Funktion asyncio.open_connection() verwendet werden können. Die beiden erforderlichen Parameter sind Host und Port.

host ist eine Zeichenfolge, die den Server angibt, zu dem eine Verbindung hergestellt werden soll, beispielsweise ein Domänenname oder eine IP-Adresse.

port ist die Socket-Portnummer, z. B. 80 für HTTP-Server, 443 für HTTPS-Server, 23 für SMTP usw.

...
# open a connection to an http server
reader, writer = await asyncio.open_connection('www.google.com', 80)

Unterstützt verschlüsselte Socket-Verbindungen über das SSL-Protokoll. Das vielleicht häufigste Beispiel ist HTTPS, das HTTP ersetzt. Dies kann erreicht werden, indem der Parameter „ssl“ auf True gesetzt wird.

...
# open a connection to an https server
reader, writer = await asyncio.open_connection('www.google.com', 443, ssl=True)

3. So starten Sie den Server

Sie können die Funktion asyncio.start_server() verwenden, um den asyncio TCP-Server-Socket zu öffnen. Dies ist eine Coroutine, die warten muss.

Diese Funktion gibt ein asyncio.Server-Objekt zurück, das den laufenden Server darstellt.

...
# start a tcp server
server = await asyncio.start_server(...)

Die drei erforderlichen Parameter sind Callback-Funktion, Host und Port. Wenn der Client eine Verbindung zum Server herstellt, wird die Rückruffunktion aufgerufen, bei der es sich um eine benannte benutzerdefinierte Funktion handelt.

Der Host ist der Domänenname oder die IP-Adresse, mit der der Client eine Verbindung herstellen möchte. Der von FTP verwendete Port ist 21 und der von HTTP verwendete Port ist 80. Bei diesen Ports handelt es sich um die Socket-Portnummern, die zum Empfangen von Verbindungen verwendet werden.

# handle connections
async def handler(reader, writer):
	# ...
...
# start a server to receive http connections
server = await asyncio.start_server(handler, '127.0.0.1', 80)

4. So verwenden Sie StreamWriter zum Schreiben von Daten

Sie können asyncio.StreamWriter verwenden, um Daten an den Socket zu übertragen. Daten werden in Bytes geschrieben. Byte-Daten können mit der Methode write() in einen Socket geschrieben werden.

...
# write byte data
writer.write(byte_data)

Alternativ können Sie die Methode writelines() verwenden, um mehrere „Zeilen“ von Bytedaten zu schreiben, die in einer Liste oder iterierbar organisiert sind.

...
# write lines of byte data
writer.writelines(byte_lines)

Es gibt keine Methoden zum Schreiben von Datenblöcken oder zum Anhalten der aufrufenden Coroutine. Nach dem Schreiben von Bytedaten leeren Sie den Socket am besten über die Methode drain(). Dabei handelt es sich um eine Coroutine, die den Aufrufer veranlassen wird, zu pausieren, bis die Daten übertragen wurden und der Socket bereit ist.

...
# write byte data
writer.write(byte_data)
# wait for data to be transmitted
await writer.drain()

5. So verwenden Sie StreamReader zum Lesen von Daten

Verwenden Sie asyncio.StreamReader, um Daten im Socket zu lesen. Die Daten werden im Byte-Format gelesen, daher müssen Zeichenfolgen möglicherweise vor der Verwendung codiert werden. Alle Lesemethoden sind Coroutinen, die warten müssen.

Sie können eine beliebige Anzahl von Bytes über die Methode read() lesen, die bis zum Ende der Datei (EOF) liest.

...
# read byte data
byte_data = await reader.read()

Zusätzlich kann über den Parameter „n“ die Anzahl der zu lesenden Bytes angegeben werden. Es könnte hilfreich sein, wenn Sie die erwartete Anzahl an Bytes für die nächste Antwort kennen.

...
# read byte data
byte_data = await reader.read(n=100)

Sie können die Methode readline() verwenden, um eine einzelne Datenzeile zu lesen. Dadurch werden Bytes zurückgegeben, bis ein Zeilenumbruch „n“ oder EOF auftritt.

Dies ist nützlich, wenn Sie das Standardprotokoll für die Bearbeitung von Textzeilen lesen.

...
# read a line data
byte_line = await reader.readline()

Zusätzlich gibt es eine readexactly()-Methode zum Lesen der genauen Anzahl von Bytes, andernfalls wird eine Ausnahme ausgelöst, und eine readuntil()-Methode, die Bytes liest, bis Bytes gelesen werden bilden.

6. So schließen Sie die Verbindung

Sie können das asyncio.StreamWriter-Objekt verwenden, um den Netzwerk-Socket zu schließen. Der Socket kann durch Aufruf der Methode close() geschlossen werden. Diese Methode blockiert nicht.

...
# close the socket
writer.close()

Obwohl die Methode close() nicht blockierend ist, können wir warten, bis der Socket vollständig geschlossen ist, bevor wir fortfahren. Dies kann durch die Methode wait_closed() erreicht werden. Dies ist eine Coroutine, die erwartet werden kann.

...
# close the socket
writer.close()
# wait for the socket to close
await writer.wait_closed()

Über die Methode is_closing() können wir überprüfen, ob der Socket geschlossen wurde oder geschlossen wird.

...
# check if the socket is closed or closing
if writer.is_closing():
	# ...

Das obige ist der detaillierte Inhalt vonSo verwenden Sie asynchrone, nicht blockierende Python-Streams. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen