11.24 asynchat -- Gestore di comando/risposta su socket asincroni

Questo modulo poggia sull'infrastruttura di asyncore, semplificando client e server asincroni e rendendo facile la gestione di protocolli i cui elementi siano terminati da stringhe arbitrarie, o di lunghezza variabile. asynchat definisce la classe astratta async_chat che sar� la vostra sotto classe, e fornir� l'implementazione dei metodi collect_incoming_data() e found_terminator(). Utilizza lo stesso ciclo asincrono di asyncore, e i due tipi di canale, asyncore.dispatcher e asynchat.async_chat possono essere liberamente mescolati nella mappa dei canali. Tipicamente un canale di server asyncore.dispatcher genera un nuovo oggetto canale asynchat.async_chat appena riceve una richiesta di connessione in ingresso.

class async_chat( )
Questa classe � una classe astratta di asyncore.dispatcher. Per farne un uso pratico nel codice, deve essere una sotto classe di async_chat, che fornir� funzionali metodi collect_incoming_data() e found_terminator(). Il metodo asyncore.dispatcher pu� essere usato, anche se non tutto ha senso in un contesto messaggio/risposta.

Come asyncore.dispatcher, async_chat definisce un insieme di eventi che vengono generati da una analisi delle condizioni del socket dopo una chiamata a select(). Una volta che il ciclo di controllo � stato avviato, i metodi dell'oggetto async_chat vengono chiamati dalla struttura di gestione eventi senza alcuna azione da parte del programmatore.

Diversamente da asyncore.dispatcher, async_chat permette di definire una fifo dei producers. Un producer necessita di un solo metodo, more(), che dovr� restituire dati che saranno trasmessi sul canale. Il producer indica esaurimento (per esempio non ci sono pi� dati) con il proprio metodo more() che restituisce una stringa vuota. A questo punto l'oggetto async_chat rimuove il producer dalla coda fifo e si avvia usando il successivo producer, se � disponibile. Quando la coda fifo del producer � vuota il metodo handle_write() non fa nulla. Utilizzare il metodo set_terminator() dell'oggetto canale per descrivere come riconoscere la sua fine, o un importante punto di interruzione, su una trasmissione in arrivo da un punto remoto.

Per costruire una sotto classe async_chat funzionale, i metodi collect_incoming_data() e found_terminator() devono gestire i dati che il canale riceve in modo asincrono. I metodi vengono descritti pi� avanti.

close_when_done( )
Inserisce un None nella coda fifo del producer. Quando questo producer viene estratto dalla coda fifo causer� la chiusura del canale.

collect_incoming_data( data)
Chiamato con data, contiene un'arbitraria quantit� di dati ricevuti. Il metodo predefinito, che deve essere sovrascritto, solleva un'eccezione NotImplementedError.

discard_buffers( )
In emergenza, questo metodo scarica ogni dato mantenuto nei buffer di input e/o output e nella coda della fifo producer.

found_terminator( )
Chiamato quando il flusso di dati in entrata corrisponde alla condizione di terminazione imposta da set_terminator. Il metodo predefinito, che deve essere sovrascritto, solleva un'eccezione NotImplementedError. I dati in input bufferizzati, devono essere disponibili attraverso un attributo dell'istanza.

get_terminator( )
Restituisce il terminatore corrente per il canale.

handle_close( )
Chiamato quando il canale � chiuso. Il metodo predefinito chiude in modo trasparente e discreto il socket del canale.

handle_read( )
Chiamato quando si scatena un evento di lettura sul socket del canale nel ciclo asincrono. Il metodo predefinito verifica la condizione di conclusione stabilita con set_terminator(), che pu� essere sia l'apparire di una particolare stringa nel flusso in entrata o la ricezione di un particolare numero di caratteri. Quando viene rinvenuta la stringa di conclusione, handle_read chiama il metodo found_terminator() dopo la chiamata a collect_incoming_data(), con tutti i dati restanti precedenti la condizione di conclusione.

handle_write( )
Chiamato quando l'applicazione deve scrivere dati sul canale. Il metodo predefinito chiama il metodo initiate_send(), che, di volta in volta chiama refill_buffer() per raccogliere i dati dal buffer fifo del producer associato al canale.

push( data)
Crea un oggetto simple_producer (vedere sotto) contenente i dati e lo inserisce nel producer_fifo del canale per assicurare la sua trasmissione. Questo � tutto quello che si deve fare per far si che il canale scriva i dati fuori, verso la rete, altrimenti � possibile utilizzare un proprio producer in un pi� complesso schema per implementare per esempio criptazione e frammentazione.

push_with_producer( producer)
Prende un oggetto producer e lo aggiunge alla coda fifo del producer associata con il canale. Quando tutti i producer attualmente inseriti sono esauriti il canale consuma i dati di questo producer chiamando il proprio metodo more() ed invia i dati al punto remoto.

readable( )
Dovrebbe restituire True per il canale che deve essere incluso nell'insieme dei canali testati dal ciclo di select() per leggibilit�.

refill_buffer( )
Rifornisce il buffer di uscita chiamando il metodo more() del producer in testa al buffer fifo. Se � esaurito, il producer viene estratto dalla fifo ed il producer successivo viene attivato. Se il producer corrente �, o diviene None, il canale viene chiuso.

set_terminator( term)
Imposta la condizione di conclusione in modo che sia riconosciuta dal canale. term pu� essere uno dei tre tipi di valore, corrispondenti ai tre differenti modi di gestire i dati del protocollo in arrivo.

term  Descrizione 
string Chiamer� found_terminator() quando la stringa viene trovata nel flusso in entrata
integer Chiamer� found_terminator() quando saranno stati ricevuti il numero di caratteri indicato
None Il canale continua a raccogliere dati per sempre

Notare che ogni dato seguito dalla stringa di conclusione sar� disponibile per la lettura da parte del canale dopo che verr� chiamato found_terminator().

writable( )
Dovrebbe restituire True tanto a lungo quanto l'elemento resta nella coda fifo del producer, o il canale � connesso ed il buffer di uscita del canale non � vuoto.



Subsections
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.