我正在使用smtplib,我正在从我的应用程序发送通知电子邮件.但是我有时会注意到(特别是当邮件发送之间有很多空闲时间时)我收到SMTPServerDisconnected错误.
我想这有两个解决方案(不知道它们都没有)
我认为第二种解决方案似乎更优雅.但是我该怎么做呢?
编辑:我正在添加代码
from smtplib import SMTP
smtp = SMTP()
smtp.connect('smtp.server.com')
smtp.login('username','password')
def notifyUser():
smtp.sendmail(from_email, to_email, msg.as_string())
Run Code Online (Sandbox Code Playgroud)
是的,您可以检查连接是否已打开.为此,请发出NOOP命令并测试状态== 250.如果没有,则在发送邮件之前打开连接.
def test_conn_open(conn):
try:
status = conn.noop()[0]
except: # smtplib.SMTPServerDisconnected
status = -1
return True if status == 250 else False
def send_email(conn, from_email, to_email, msg):
if not test_conn_open(conn):
conn = create_conn()
conn.sendmail(from_email, to_email, msg.as_string())
return conn # as you want are trying to reuse it.
Run Code Online (Sandbox Code Playgroud)
请注意,这样做是因为打开连接,比如用gmail,消耗时间,比如2-3秒.随后,为了优化发送您可能拥有的多封电子邮件,您还应该遵循Pedro的回复(最后一部分).
如果您的用例一次只发送一条消息,那么对我来说最合适的解决方案是为每条消息创建一个新的SMTP会话:
from smtplib import SMTP
smtp = SMTP('smtp.server.com')
def notifyUser(smtp, smtp_user, smtp_password, from_email, to_email, msg):
smtp.login(smtp_user, smtp_password)
smtp.sendmail(from_email, to_email, msg.as_string())
smtp.quit()
Run Code Online (Sandbox Code Playgroud)
如果您的SMTP服务器不需要您自己进行身份验证(常见情况),则可以进一步简化为:
from smtplib import SMTP
smtp = SMTP('smtp.server.com')
def notifyUser(smtp, from_email, to_email, msg):
smtp.sendmail(from_email, to_email, msg.as_string())
smtp.quit()
Run Code Online (Sandbox Code Playgroud)
如果通常一次发送多条消息,并且您希望通过为消息组重用相同的SMTP会话来优化此情况(如果您不需要登录SMTP,可以简化为上述情况)服务器):
from smtplib import SMTP
smtp = SMTP('smtp.server.com')
def notifyUsers(smtp, smtp_user, smtp_password, from_to_msgs):
"""
:param from_to_msgs: iterable of tuples with `(from_email, to_email, msg)`
"""
smtp.login(smtp_user, smtp_password)
for from_email, to_email, msg in from_to_msgs:
smtp.sendmail(from_email, to_email, msg.as_string())
smtp.quit()
Run Code Online (Sandbox Code Playgroud)