2012-11-06 127 views
15

我使用SwiftMailer從gearman工作進程發送電子郵件。我正在使用Swift_SmtpTransport類發送電子郵件。如何關閉SwiftMailer中的Smtp連接

問題是,如果此工作進程保持空閒一段時間,SwiftMailer smtp連接超時。現在,當下一份工作到達時,由於連接超時,SwiftMailer無法發送電子郵件。

理想情況下,我想在每項工作後關閉smtp連接。我無法找到這個具體做這個類的api。由於這是一個靜態類,因此unset()對象也不起作用。

+2

也許:$ transport-> stop(),$ transport-> start() – 2012-11-06 19:21:43

+0

@Dragon Omg ty太多了!我有一個無限循環的後臺工作人員,這爲我解決了這個問題。 –

回答

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

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

這樣,斯威夫特檢測郵包停止並自動啓動它,所以它從通信錯誤恢復正常。

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