Node.js/NodeMailer/Express/Outlook smtp主机-超过了并发连接限制



希望你一切顺利。我正在开发一个使用express和nodemailer的应用程序。我的应用程序成功地发送了电子邮件,但问题是,我无法以我想要的方式一次发送一封电子邮件。我不想在"收件人"字段中放入地址数组,我希望每个电子邮件都单独发送。

我在这方面取得了成功,但存在一个问题。微软似乎已经制定了某种限制,防止应用程序一次拥有超过一定数量的连接。(链接到帖子文档末尾的解释。)

我曾试图通过一些权宜之计来解决这个问题。不是所有的,我会麻烦你的。其中大多数涉及CCD_ 1和CCD_ 2或CCD_。我不打算发送那么多电子邮件——当然也不是为了达到任何标准。我甚至不想在我的电子邮件中使用任何HTML。只是纯文本。然而,当我的应用程序发送2/3的电子邮件时,我会遇到他们的错误消息(响应代码432)。

下面你会看到我的代码。

  • 正如你所看到的,我甚至愿意尝试将我的增量器添加到setInterval中,就好像更改电子邮件发送的间隔实际上会有所帮助一样
  • 现在,这正在发送一些电子邮件,但我最终遇到了这个障碍。这种情况通常发生在2/3的电子邮件上。然而,奇怪的是,它前后矛盾

这是我的代码的第一个相关部分。

db.query(sqlEmailGetQuery, param)
.then(result => {
handleEmail(result, response);
}).catch(error => {
console.error(error);
response.status(500).json({ error: 'an unexpected error occured.' });
});
});

这是它的第二部分

function handleEmail(result, response) {
const email = result.rows[0];
let i = 0;
email.json_agg.map(contact => {
const msg = {
from: process.env.EMAIL_USER,
to: email.json_agg[i].email,
subject: email.subject,
text: email.emailBody + ' ' + i
};
i++;
return new Promise((resolve, reject) => {
setInterval(() => {
transporter.sendMail(msg, function (error, info) {
if (error) {
return console.log(error);
} else {
response.status(200).json(msg);
transporter.close();
}
});
}, 5000 + i);
});
});
}
  • 我最初尝试了一个简单的for循环来遍历可迭代的联系人email.json_agg[i].email,但很明显,当我达到连接限制时,它就停止了工作
  • 我来到stackoverflow,回顾了性质相似的问题。例如,这个问题几乎是相似的,但这家伙有8000多个连接,如果你阅读我在下面发布的微软规则,他们在他发布该帖子后实现了连接规则
  • 我尝试过setIntervalforEachawait,因为它与每个承诺都相连,但由于这不是问题的根源,所以也不起作用
  • 我已经尝试了与您上面看到的类似的代码,只是我将间隔设置为20秒

随着我对这个问题的理解不断加深,我发现我要么必须想办法等待足够长的时间,这样我才能发送另一封电子邮件——而不会出现连接超时的情况,要么每次发送电子邮件时都断开连接,这样当我发送下一封电子邮件时,我就有了新的连接。在我看来,如果后者是可能的,那么每个人都会这样做,并违反微软的政策。

有没有办法让我绕过这个问题,每隔3秒发送3封电子邮件,然后等待,再发送3封?电子邮件的数量如此之大,如果有必要,我可以等十秒钟。是否有其他限制较少的smtp主机?

请告诉我你的想法。如果有帮助的话,我的传输配置如下。

const transporter = nodemailer.createTransport({
pool: true,
host: 'smtp-mail.outlook.com',
secureConnection: false,
maxConnections: 1,
port: 587,
secure: false,
tls: { ciphers: 'SSLv3' },
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
}
});

https://learn.microsoft.com/en-us/exchange/troubleshoot/send-emails/smtp-submission-improvements#new-提交消息的并发连接的限制

首先,向大量用户发送同一封电子邮件的最有效方法是将其发送给自己并抄送所有收件人。这将允许您向SMTP服务器发送一封电子邮件,然后它将该电子邮件分发给所有收件人,而没有收件人能够看到任何单个收件人的电子邮件地址。

其次,您无法使用计时器来可靠地控制一次运行的请求数量,因为计时器与给定请求完成所需的时间无关,因此计时器只是对请求平均时间的猜测,它们可能在某些情况下工作,而在响应较慢时不工作。相反,您必须实际使用一个请求的完成来知道是否可以发送下一个请求。

如果你仍然想发送单独的电子邮件,并连续发送电子邮件,一个接一个,以避免一次处理过多的电子邮件,你可以这样做:

async function handleEmail(result) {
const email = result.rows[0];
for (let [i, contact] of email.json_agg.entries()) {
const msg = {
from: process.env.EMAIL_USER,
to: contact.email,
subject: email.subject,
text: email.emailBody + ' ' + i
};
await transporter.sendMail(msg);
}
}

如果您不将回调传递给transporter.sendMail(),那么它将返回一个您可以直接使用的promise,而无需将其封装在自己的promise中。

请注意,此代码不会向您的http请求发送响应,因为这应该是调用代码的责任,而您以前的代码试图为每封电子邮件发送响应,而您只能发送一个响应,而如果出现错误,以前的代码不会发送任何响应。

此代码依赖于返回给调用者的promise来传达它是成功的还是遇到错误,然后调用者可以决定如何处理这种情况。

您可能也不应该将result传递给此函数,而应该只传递setInterval()0,因为此代码没有理由知道它必须访问某些数据库查询结果才能获得所需的值。这应该是打电话的人的责任。然后,这个函数就更通用了。

如果你想一次发送N封电子邮件,而不是一次发送一封电子邮件,你可以使用mapConcurrent()之类的东西来做到这一点。它迭代一个数组,并同时保持最多N个请求。

相关内容

  • 没有找到相关文章

最新更新