asyncore - Asynchroner IO/Handler
Link
zu Doug Hellmanns Original Artikel
| Zweck: |
Asynchrones IO Handling |
| Python: |
ab 1.5.2 |
Das asyncore Modul beinhaltet Tools um mit IO-Objekten wie mit Sockets zu arbeiten, so dass diese
asynchron verwaltet werden können (anstelle von threading zum Beispiel). Die Hauptklasse, die
zur Verfügung gestellt wird ist der dispatcher, ein Wrapper um einen Socket der beim Aufruf der Hauptschleife loop() mit Hooks zur
Ereignissen wie verbinden, lesen und schreiben verwaltet.
Clients
Erstelle eine Subklasse von dispatcher um einen auf asynchore basierenden Client zu erstellen und
Implementierungen zum Erstellen, Lesen und Schreiben von Sockets zur Verfügung zu stellen. Laßt uns diesen,
auf der Dokumentation der Standarbibliothek basierenden HTTP Client, untersuchen.
import asyncore
import logging
import socket
from cStringIO import StringIO
import urlparse
class HttpClient(asyncore.dispatcher):
def __init__(self, url):
self.url = url
self.logger = logging.getLogger(self.url)
self.parsed_url = urlparse.urlparse(url)
asyncore.dispatcher.__init__(self)
self.write_buffer = 'GET %s HTTP/1.0\r\n\r\n' % self.url
self.read_buffer = StringIO()
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
address = (self.parsed_url.netloc, 80)
self.logger.debug('Verbinde mit %s', address)
self.connect(address)
def handle_connect(self):
self.logger.debug('handle_connect()')
def handle_close(self):
self.logger.debug('handle_close()')
self.close()
def writable(self):
is_writable = (len(self.write_buffer) > 0)
if is_writable:
self.logger.debug('writable() -> %s', is_writable)
return is_writable
def readable(self):
self.logger.debug('readable() -> True')
return True
def handle_write(self):
sent = self.send(self.write_buffer)
self.logger.debug('handle_write() -> "%s"', self.write_buffer[:sent])
self.write_buffer = self.write_buffer[sent:]
def handle_read(self):
data = self.recv(8192)
self.logger.debug('handle_read() -> %d bytes', len(data))
self.read_buffer.write(data)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(name)s: %(message)s',
)
clients = [
HttpClient('http://www.python.org/'),
HttpClient('http://www.doughellmann.com/PyMOTW/contents.html'),
]
logging.debug('STARTE SCHLEIFE')
asyncore.loop()
logging.debug('BEENDE SCHLEIFE')
for c in clients:
response_body = c.read_buffer.getvalue()
print c.url, 'got', len(response_body), 'bytes'
Als erstes wird der Socket in __init__() mit der Methode create_socket() aus der Basisklasse erstellt.
In der Übersetzung