Непрерывное соединение с сервером электронной почты с использованием JAVA Mail API

Мы нацелены на разработку службы, которая всегда остается подключенной к серверу электронной почты, чтобы всякий раз, когда пользователь запускает почту, он отправлялся с использованием соединения вместо получения нового соединения и отправки почты. Возможно ли, что мы всегда остаемся подключенными к почтовому серверу, используя JAVA Mail API??. пожалуйста, помогите мне в этом.

3 ответа

Решение

При подключении к SMTP-серверу (также при использовании javax.mail API), вы используете сокетное соединение (см. Src классов SMTPTransport и Transport). Сокеты позволяют подключаться к удаленному серверу, и это соединение остается открытым до тех пор, пока оно не будет закрыто явно. Это означает, что теоретически вы можете создать соединение, а они снова его использовать.

Тем не менее, многие SMTP-серверы являются довольно злыми и разрушают соединение, если вы используете его "слишком медленно" или если вы часто пытаетесь повторно использовать ваш SMTP-сеанс. (Я посмотрел настройки постфикса для вас.)

Java Mail API позволяет создавать соединение и закрывать его в любое время. Что-л. как это:

        Transport transport = session.getTransport("smtp");
        transport.connect();
        transport.sendMessage(msg, addressArray);
        // you can do transport.close(); later

Однако из-за того, как работают SMTP-серверы, вы не можете просто выполнить connect() один раз и забудь об этом. Самое большее, что вы можете сделать, - это правильно обрабатывать принудительное отключение путем повторного подключения. Для этого в Java Mail API есть механизм уведомления (взгляните на использование notifyConnectionListeners метод)

Если вы хотите всегда подключенное соединение, вы должны создать свой транспорт вне метода отправки, но чтобы избежать исключений при отправке (SMTPSendFailedException 421 Timeout data client), вы должны проверить, подключен ли транспорт, и если нет, подключить его снова перед отправкой:

 if (!transport.isConnected())//make sure the connection is alive
            transport.connect();
 transport.sendMessage(message, message.getAllRecipients());

Однако из-за того, как работают SMTP-серверы, вы не можете просто выполнить connect() один раз и забыть его. Самое большее, что вы можете сделать, - это правильно обрабатывать принудительное отключение путем повторного подключения.

Согласовано!

Фактически вы можете повторно использовать SMTP-соединение JavaMail, используя следующую логику:

Transport transport = null;
MimeMessage message = null;

Properties prop = new Properties();
// load all smtp properties

Session session = Session.getDefaultInstance(prop, null);
transport = session.getTransport("smtp");

for (EachMail eachMail : list) {
    if (!transport.isConnected()) {
        if (port != null && port.length() > 0) {
            transport.connect(host, Integer.parseInt(port), "<username>", "<password>");
        } else {
            transport.connect(host, "<username>", "<password>");
        }
    }

    // set all mail attributes from eachMail object
    message.saveChanges();
    transport.sendMessage(message, message.getAllRecipients());
}

Работает как шарм. Ура!

Другие вопросы по тегам