# `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ólnienia `async_chat`, dostarczając sensownego wypełnienia sposobu postępowania `collect_incoming_data()` i sposobu postępowania `found_terminator()`. Sposoby postępowania uogólnienia `asyncore.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 a `select()` call. Once the polling loop has been started the `async_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 its `more()` method return the empty bytes object. At this point the `async_chat` object removes the producer from the queue and starts using the next producer, if any. When the producer queue is empty the `handle_write()` method does nothing. You use the channel object’s `set_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 wprowadzania `collect_incoming_data()` i `found_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ątek `NotImplementedError`. 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ściowym
  integer - z ang. - liczba całkowita | Wywoła `found_terminator()` gdy wskazana liczba znaków zostanie odebrana
  `None` - 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()