2012-11-06 3 views
15

Я использую SwiftMailer для отправки писем от рабочего процесса редуктора. Я использую класс Swift_SmtpTransport для отправки писем.Как закрыть соединение Smtp в SwiftMailer

Проблема заключается в том, что если этот рабочий процесс на какое-то время остается бездействующим, соединение SMTP SwiftMailer истекает. Теперь, когда приходит следующая работа, SwiftMailer не может отправлять электронные письма по истечении времени соединения.

В идеале, я хотел бы закрыть соединение smtp после каждой работы. Я не могу найти api в классе, который делает это специально. Также не работает объект unset(), так как это статический класс.

+2

возможно: $ транспортно> остановка(), $ транспортно> начать() –

+0

@Dragon Omg ти так много! У меня есть рабочий стол в бесконечном цикле, и это решило его для меня. –

ответ

0

Я бегу работника в бесконечном цикле, используя SwiftMailer и AWS SES я получаю сообщение об ошибке:

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

решение для моего сценария:

$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

В этом ответе можно использовать эксплантацию. Вы имеете в виду, что такая ошибка не бросала 'Swift_TransportException', но это явно исправляет проблему? –

+3

Это ответ или вопрос? – caponica

1

я получил такое же исключение с symfony2 при отправке большого количества писем с использованием SwiftMailer и AWS SES.

Я мог бы исправить свою проблему, начав и останавливая транспортный уровень каждый раз. Посмотрите на мое сообщение в блоге для получения дополнительной информации: http://www.prowebdev.us/2013/06/swiftmailersymfony2-expected-response.html

10

Существует грубая опция: запретить транспортировку явно. При последующих вызовах метода sendMail SwiftMailer проверяет, вверх ли транспорт (он не сейчас), и запустите его снова. IMNSHO, SwiftMailer должен перехватить SMTP таймаут и снова automatically.But, на данный момент, это временное решение:

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

Я посылаю почту в цикле, и я ловил Swift_TransportException и создание нового экземпляра Swift_Mailer но это не было правильное исправление: проблема в том, что транспорт, а не почта. Решение состоит в том, чтобы выдать явный вызов 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 ;-) 
    } 
} 

Таким образом, Swift обнаруживает почтовая программа останавливается, и запускает его автоматически, так что это правильно оправится от ошибок связи.

+1

Но разве вы не должны повторять отправку? – tishma

+0

@tishma Вопрос задает вопрос о том, как правильно сбросить почтовую программу, и это то, на что я пытаюсь ответить. –

+0

Когда труба сломана '$ mailer-> getTransport() -> stop()' не удастся – Jekis

1

Когда труба сломана $ mailer-> getTransport() -> stop() также не удастся. И из-за этой ошибки транспорт не может быть остановлен. Для устранения этой проблемы

// 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); 
     } 
    } 
} 
Смежные вопросы