2012-11-06 11 views
15

Używam SwiftMailer do wysyłania wiadomości e-mail z procesu pracownika gearman. Używam klasy Swift_SmtpTransport do wysyłania e-maili.Jak zamknąć połączenie Smtp w SwiftMailer

Problem polega na tym, że jeśli ten proces roboczy nie będzie działał przez jakiś czas, upłynie czas połączenia smtp SwiftMailer. Teraz, gdy pojawia się następne zadanie, SwiftMailer nie wysyła wiadomości e-mail, gdy upłynął limit czasu połączenia.

Idealnie chciałbym zamknąć połączenie smtp po każdym zadaniu. Nie mogę znaleźć api w klasie, która robi to specjalnie. Nie działa też obiekt unset(), ponieważ jest to klasa statyczna.

+2

może: $ z transportem> stop(), $ z transportem> start() –

+0

@Dragon Omg ty tak dużo! Mam pracownika w tle w nieskończonej pętli i to rozwiązało to dla mnie. –

Odpowiedz

0

biegnę pracownika w nieskończonej pętli przy użyciu Swiftmailer i AWS SES byłem coraz błąd:

Expected response code 250 but got code "421", with message "421 Timeout waiting for data from client. 

rozwiązanie dla mojego skryptu:

$love = true; 
while($love) { 
    $message = Message::to($record->to) 
     ->from(array('[email protected]' => $user->name())) 
     ->reply(array($user->email => $user->name())) 
     ->subject($record->subject) 
     ->body($body->value) 
     ->html(true) 
     ->send(); 

    if (! $message->was_sent()) 
     throw new Swift_TransportException($errstr . ': ' . $errno); 
} 
+2

Ta odpowiedź może posłużyć się eksplansem. Czy masz na myśli, że taki błąd nie rzucił 'Swift_TransportException', ale czy to wyraźnie rozwiązuje problem? –

+3

Czy to jest odpowiedź lub pytanie? – caponica

10

Istnieje nieuprzejma opcja: zatrzymaj transport jawnie. Podczas kolejnych wywołań metody sendMail, SwiftMailer sprawdzi, czy transport jest w górze (to nie jest, teraz) i uruchom go ponownie. IMNSHO, SwiftMailer powinien przechwytywać czas oczekiwania SMTP i ponownie automatically.But, na razie, jest to obejście:

function sendMail($your_args) { 
    try{ 
     $mailer = Swift_Mailer::newInstance($transport); 
     $message = Swift_Message::newInstance('Wonderful Subject') 
     ->setFrom(array('[email protected]' => 'John Doe')) 
     ->setTo(array('[email protected]', '[email protected]' => 'A name')) 
     ->setBody('Here is the message itself'); 

     $result = $mailer->send($message); 
     $mailer->getTransport()->stop(); 

    } catch (Swift_TransportException $e) { 
     //this should be caught to understand if the issue is on transport 
    } catch (Exception $e) { 
     //something else happened 
    } 

} 
6

mogę wysyłać maili w pętli, a ja łapanie Swift_TransportException i tworzenie nowej instancji Swift_Mailer ale To nie była właściwa poprawka: problemem jest transport , a nie mailer. Rozwiązaniem jest wydać wyraźne wezwanie do Swift_SmtpTransport::stop():

foreach($recipients as $to => $body){ 
    try{ 
     $message->setTo($to); 
     $message->setBody(body); 
     $mailer->send($message); 
    }catch(Swift_TransportException $e){ 
     $mailer->getTransport()->stop(); 
     sleep(10); // Just in case ;-) 
    } 
} 

ten sposób wykrywa Swift Mailer jest zatrzymany i uruchamia go automatycznie, dzięki czemu odzyskuje poprawnie z błędów komunikacyjnych.

+1

Ale czy nie powinieneś ponawiać próby wysłania? – tishma

+0

@tishma Pytanie, jak poprawnie zresetować program pocztowy i na to właśnie próbuję odpowiedzieć. –

+0

Kiedy potok jest uszkodzony '$ mailer-> getTransport() -> stop()' zawiedzie – Jekis

1

Kiedy rura jest uszkodzona, $ mailer-> getTransport() -> stop() również się nie powiedzie. A z powodu tego błędu transport nie może zostać zatrzymany. Rozwiązaniem jest

// Let's try to send an email. 
$tries = 3; 
while ($tries--) { 
    try { 
     $sent = $this->mailer->send($message); 
     break; 
    } catch (\Exception $e) { 
     // Connection problems 
     // @see https://github.com/swiftmailer/swiftmailer/issues/490 
     try { 
      // Try to stop 
      $this->mailer->getTransport()->stop(); 
     } catch (\Exception $e) { 
      // Got Exception while stopping transport. 
      // We have to set _started to 'false' manually, because due to an exception it is 'true' now. 
      $t = $this->mailer->getTransport(); 
      $reflection = new \ReflectionClass($t); 
      $prop = $reflection->getProperty('_started'); 
      $prop->setAccessible(true); 
      $prop->setValue($t, false); 
      $prop->setAccessible(false); 
     } 
    } 
} 
Powiązane problemy