Как закрыть соединение Smtp в SwiftMailer - программирование
Подтвердить что ты не робот

Как закрыть соединение Smtp в SwiftMailer

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

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

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

4b9b3361

Ответ 1

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

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  
    }

}

Ответ 2

Я отправляю письма в цикле, и я ловил 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 обнаруживает, что почтовая программа остановлена ​​и запускает ее автоматически, поэтому она правильно восстанавливается из-за ошибок связи.

Ответ 3

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

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

Ответ 4

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

// Let 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);
        }
    }
}

Ответ 5

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

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

Решение для моего script:

$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);
}