如何在 SwiftMailer 中关闭 Smtp 连接

2022-08-31 00:58:54

我使用 SwiftMailer 从 Gearman worker 流程发送电子邮件。我正在使用该类发送电子邮件。Swift_SmtpTransport

问题是,如果此工作进程在一段时间内保持空闲状态,SwiftMailer smtp 连接将超时。现在,当下一个作业到达时,SwiftMailer 无法发送电子邮件,因为连接已超时。

理想情况下,我希望在每个作业后关闭smtp连接。我无法在专门执行此操作的类中找到 api。对象也不起作用,因为这是一个静态类。unset()


答案 1

我在循环中发送邮件,我正在捕获并创建一个新的实例,但这不是正确的解决方案:问题在于传输,而不是邮件程序。解决方案是发出显式调用 :Swift_TransportExceptionSwift_MailerSwift_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 可以检测到邮件程序已停止并自动启动它,因此它可以从通信错误中正确恢复。


答案 2

有一个粗鲁的选择:明确停止传输。在随后调用 sendMail 方法时,SwiftMailer 将检查传输是否启动(现在不是),然后重新启动它。IMNSHO,SwiftMailer应该拦截SMTP超时并自动重新连接。但是,就目前而言,这是解决方法:

function sendMail($your_args) {
    try{ 
      $mailer = Swift_Mailer::newInstance($transport);
      $message = Swift_Message::newInstance('Wonderful Subject')
        ->setFrom(array('john@doe.com' => 'John Doe'))
        ->setTo(array('receiver@domain.org', 'other@domain.org' => '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  
    }

}

推荐