Potrzebuję utworzyć klasę, która może odbierać i przechowywać wiadomości SMTP, tj. Wiadomości e-mail. Aby to zrobić, używam asyncore
zgodnie z przykładem opublikowanym here. Jednak asyncore.loop()
jest blokowany, więc nie mogę zrobić nic więcej w kodzie.Jak obsługiwać asyncore w klasie w python, bez blokowania czegokolwiek?
Więc pomyślałem o użyciu wątków. Oto przykładowy kod, który pokazuje, co mam na myśli:
class MyServer(smtpd.SMTPServer):
# derive from the python server class
def process_message(..):
# overwrite a smtpd.SMTPServer method to be able to handle the received messages
...
self.list_emails.append(this_email)
def get_number_received_emails(self):
"""Return the current number of stored emails"""
return len(self.list_emails)
def start_receiving(self):
"""Start the actual server to listen on port 25"""
self.thread = threading.Thread(target=asyncore.loop)
self.thread.start()
def stop(self):
"""Stop listening now to port 25"""
# close the SMTPserver from itself
self.close()
self.thread.join()
Mam nadzieję, że dostaniesz zdjęcie. Klasa MyServer
powinna mieć możliwość uruchamiania i zatrzymywania odsłuchiwania portu 25 w sposób nieblokujący, który może być sprawdzany w poszukiwaniu wiadomości podczas słuchania (lub nie). Metoda start
uruchamia detektor asyncore.loop()
, który po odebraniu wiadomości e-mail dołącza się do listy wewnętrznej. Podobnie, metoda stop
powinna być w stanie zatrzymać ten serwer, zgodnie z sugestią here.
Pomimo faktu, kod ten nie działa jak oczekuję (asyncore wydaje się działać zawsze, nawet zadzwonię powyższy stop
metody. Na error
podniosę jest przechwycony w ciągu stop
, ale nie wewnątrz funkcji target
zawierającej asyncore.loop()
) Nie jestem pewien, czy moje podejście do problemu jest sensowne. Sugerowane są wszelkie sugestie dotyczące naprawienia powyższego kodu lub zaproponowania bardziej solidnej implementacji (bez przy użyciu oprogramowania innej firmy).
Czuję tam pewne zamieszanie. Jaki jest problem z blokowaniem 'asyncore.loop()'? Czy rozumiesz, dlaczego nazywasz funkcję 'loop' i co ona robi? – mmgp
@mmgp: Problem z 'asyncore.loop()' polega na tym, że blokuje.Chcę móc korzystać z klasy w dowolnym czasie w ramach innego kodu. Z drugiej strony nie jestem ekspertem od 'asyncore.loop()', ale AFAIK obsługuje wewnętrznie 'select.select', który szuka np. dla przychodzących wiadomości SMTP na porcie 25, w tym przypadku. – Alex
czy używałeś narzędzi GUI? Zasadniczo wszystkie z nich oparte są na pętlach zdarzeń. Musisz tak zorganizować rzeczy, aby tworzyły zdarzenia do obsłużenia przez "pętlę zdarzeń". Zamieszanie, o którym wspomniałem, jest takie, że wydaje się, że nie zdajesz sobie sprawy z używania pętli zdarzeń, czy tak jest w przypadku? – mmgp