asynchat
— Asynchroniczna obsługa gniazda komend/odpowiedzi.¶
Source code: Lib/asynchat.py
Niezalecane od wersji 3.6: Please use asyncio
instead.
Informacja
This module exists for backwards compatibility only. For new code we
recommend using asyncio
.
Ten moduł buduje na infrastrukturze modułu asyncore
, upraszczając klientów i serwery asynchroniczne i czyniąc łatwiejszym obsługę protokołów których elementy są zakańczane przez zadane ciągi znaków, lub są zmiennej długości. Moduł asynchat
określa abstrakcyjne uogólnienie async_chat
które możesz dostosować tworząc własne podrzędne uogólnienie, dostarczając wypełnień sposobów postępowania collect_incoming_data()
i found_terminator()
. Używa tej samej asynchronicznej pętli co moduł asyncore
, i dwóch rodzajów kanałów, - asyncore.dispatcher
i asynchat.async_chat
, mogą być dowolnie być mieszane w mapie kanałów. Typowo kanał serwera asyncore.dispatcher
generuje nowe obiekty kanałów asynchat.async_chat
gdy otrzymuje wchodzące zapytania o połączenie.
-
class
asynchat.
async_chat
¶ To uogólnienie jest abstrakcyjnym uogólnieniem podrzędnym względem uogólnienia
asyncore.dispatcher
. Aby praktycznie użyć kodu musisz dostosować podrzędne uogólnienie względem uogólnieniaasync_chat
, dostarczając sensownego wypełnienia sposobu postępowaniacollect_incoming_data()
i sposobu postępowaniafound_terminator()
. Sposoby postępowania uogólnieniaasyncore.dispatcher
mogą być używane, chociaż nie wszystkie mają sens w kontekście wiadomość/odpowiedź.Like
asyncore.dispatcher
,async_chat
defines a set of events that are generated by an analysis of socket conditions after aselect()
call. Once the polling loop has been started theasync_chat
object’s methods are called by the event-processing framework with no action on the part of the programmer.Dwie właściwości uogólnienia mogą być modyfikowane, aby poprawić wydajność, lub nawet aby możliwie oszczędzać pamięć.
-
ac_in_buffer_size
¶ Rozmiar przestrzeni wymiany wejściowej asynchronicznej (domyślnie
4096
).
-
ac_out_buffer_size
¶ Rozmiar przestrzeni wymiany wyjściowej asynchronicznej (domyślnie
4096
).
Unlike
asyncore.dispatcher
,async_chat
allows you to define a FIFO queue of producers. A producer need have only one method,more()
, which should return data to be transmitted on the channel. The producer indicates exhaustion (i.e. that it contains no more data) by having itsmore()
method return the empty bytes object. At this point theasync_chat
object removes the producer from the queue and starts using the next producer, if any. When the producer queue is empty thehandle_write()
method does nothing. You use the channel object’sset_terminator()
method to describe how to recognize the end of, or an important breakpoint in, an incoming transmission from the remote endpoint.Aby zbudować funkcjonujące podrzędne uogólnienia względem uogólnienia
async_chat
, twoje sposoby postępowania wprowadzaniacollect_incoming_data()
ifound_terminator()
muszą obsługiwać dane które kanał otrzymuje asynchronicznie. Sposoby postępowania są opisane poniżej.-
-
async_chat.
close_when_done
()¶ Pushes a
None
on to the producer queue. When this producer is popped off the queue it causes the channel to be closed.
-
async_chat.
collect_incoming_data
(data)¶ Wywoływany z danymi przechowując określoną ilość otrzymanych danych. Domyślny sposób postępowania, który musi zostać przesłonięty, zgłasza wyjątek
NotImplementedError
.
-
async_chat.
discard_buffers
()¶ In emergencies this method will discard any data held in the input and/or output buffers and the producer queue.
-
async_chat.
found_terminator
()¶ Wywoływana gdy przychodzący strumień danych odpowiada warunkowi zakończenia ustawionemu przez sposób postępowania
set_terminator()
. Domyślny sposób postępowania, który musi być przesłonięty, zgłasza wyjątekNotImplementedError
. Dane wejściowe z przestrzeni wymiany powinny być dostępne przez właściwość przykładu.
-
async_chat.
get_terminator
()¶ Zwraca obecne zakończenie dla kanału.
-
async_chat.
push
(data)¶ Pushes data on to the channel’s queue to ensure its transmission. This is all you need to do to have the channel write the data out to the network, although it is possible to use your own producers in more complex schemes to implement encryption and chunking, for example.
-
async_chat.
push_with_producer
(producer)¶ Takes a producer object and adds it to the producer queue associated with the channel. When all currently-pushed producers have been exhausted the channel will consume this producer’s data by calling its
more()
method and send the data to the remote endpoint.
-
async_chat.
set_terminator
(term)¶ Ustawia warunek zakończenia aby był rozpoznany przez kanał.
term
może być dowolną z trzech typów wartości, odpowiadających trzem różnym sposobom obsługi przychodzących danych protokołu.term - z ang. - termin
Opis
ciąg znaków
Wywoła sposób postępowania
found_terminator()
gdy ciąg znaków zostanie znaleziony w strumieniu wejściowyminteger - z ang. - liczba całkowita
Wywoła
found_terminator()
gdy wskazana liczba znaków zostanie odebranaNone
- z ang. -Żaden
Kanał nadal zbiera dane w pętli nieskończonej
Zauważ że dowolne dane następujące po terminatorze będą dostępne dla przeczytania przez kanał po tym jak sposób postępowania
found_terminator()
zostanie wywołany.
Przykład asynchat¶
Następujący częściowy przykład pokazuje jak zapytania HTTP mogą być wczytane za pomocą async_chat
. Serwer sieci może tworzyć obiekt http_request_handler
dla każdego przychodzącego połączenia klienckiego. Zauważ że początkowo zakończenie kanału jest ustalone aby odpowiadało pustej linii na końcu nagłówka HTTP, i flaga wskazująca że nagłówki są wczytywane.
Gdy już nagłówki zostaną wczytane, jeśli zapytanie jest typu POST (wskazując na to że dalsze dane są obecne w strumieniu wejściowym) wtedy nagłówek Content-Length:
jest używany aby ustawić numeryczny terminator do wczytania właściwej ilości danych z kanału.
Metoda handle_request()
jest wywoływane gdy już całe istotne wejście zostało pobrane, po ustawieniu terminatora kanału na None
- z ang. - Żaden
aby upewnić się że jakiekolwiek nadmiarowe dane przesyłane przez klienta sieci są ignorowane.
import asynchat
class http_request_handler(asynchat.async_chat):
def __init__(self, sock, addr, sessions, log):
asynchat.async_chat.__init__(self, sock=sock)
self.addr = addr
self.sessions = sessions
self.ibuffer = []
self.obuffer = b""
self.set_terminator(b"\r\n\r\n")
self.reading_headers = True
self.handling = False
self.cgi_data = None
self.log = log
def collect_incoming_data(self, data):
"""Buffer the data"""
self.ibuffer.append(data)
def found_terminator(self):
if self.reading_headers:
self.reading_headers = False
self.parse_headers(b"".join(self.ibuffer))
self.ibuffer = []
if self.op.upper() == b"POST":
clen = self.headers.getheader("content-length")
self.set_terminator(int(clen))
else:
self.handling = True
self.set_terminator(None)
self.handle_request()
elif not self.handling:
self.set_terminator(None) # browsers sometimes over-send
self.cgi_data = parse(self.headers, b"".join(self.ibuffer))
self.handling = True
self.ibuffer = []
self.handle_request()