ssl.SSLEOFError在通过Django发送电子邮件时

时间:2017-08-02 12:18:17

标签: django django-email

设置

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_USE_TLS = True

EMAIL_HOST = 'smtp.gmail.com'

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER = 'no_reply@domain.com'

SERVER_EMAIL = 'no_reply@domain.com'

DEFAULT_DO_NOT_REPLY = 'User <no_reply@domain.com>'

EMAIL_HOST_PASSWORD = 'xxxxxxxxx'

EMAIL_PORT = 587

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

class EmailThread(threading.Thread):
    def __init__(self, subject, context, recipient, template):
        self.subject = subject
        self.recipient = recipient
        self.message = get_template(template).render(context)
        threading.Thread.__init__(self)

    def run(self):
        msg = EmailMessage(
            subject=self.subject,
            from_email=settings.DEFAULT_DO_NOT_REPLY,
            to=self.recipient,
            body=self.message
        )
        msg.content_subtype = "html"

        try:
            msg.send(fail_silently=False)
            log.info("E-mail triggered. Subject: '%s', to: %s" % (self.subject, self.recipient))
        except Exception as e:
            log.exception(e)

用法

def notify_admin_blocked_account(user):
    """
    Sends sends an email when the account is blocked
    :return:
    """
    email = EmailThread(
        subject='{}, your account has been blocked'.format(user),
        context={
            'user': user,
            'login_attempts': settings.MAX_STAFF_PWD_ATTEMPTS,
        },
        recipient=[user.email,],
        template='mail/notify_admin_blocked_account.html'
    )
    email.start()

错误

[ERROR][2017-08-01 10:40:26,835][mail] EOF occurred in violation of protocol (_ssl.c:645)
Traceback (most recent call last):
  File "./bin/mail.py", line 27, in run
    msg.send(fail_silently=False)
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/message.py", line 348, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 104, in send_messages
    new_conn_created = self.open()
  File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 69, in open
    self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile)
  File "/usr/lib/python3.5/smtplib.py", line 766, in starttls
    server_hostname=self._host)
  File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 752, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:645)

当我尝试使用Django发送电子邮件(异步)时,我有一些奇怪的行为。我真的想避免安装第三方应用程序以减少代码碎片 - 特别是其中一些似乎使用crontab。

值得注意的是,错误并不是一直发生的。但是,即使它没有发生,有时也不会发送电子邮件。只有部分人能够通过。

在我的开发环境中运行良好,我可以发送电子邮件。但是,在我的生产环境(EC2实例)上,它根本不起作用。

如果我通过正常流程触发电子邮件,则不会发送。如果我登录到服务器,打开manage.py shell,导入项目并调用发送电子邮件的功能,有时我会收到触发和手动触发的电子邮件或收到错误(下面的一个)。

1 个答案:

答案 0 :(得分:0)

我的解决方案是使用Django-Mailer。它会破坏项目,这是我想要避免的,但它的使用非常简约。