Рубрики
Uncategorized

Простое использование redis для асинхронной отправки почты

Автор оригинала: David Wong.

Вы тоже застряли в красном, зная, почему это так, и как им пользоваться? Простой пример использования очередей сообщений для асинхронной отправки сообщений в Yii

Подготовка к повторному обследованию~~

Прежде всего, вам необходимо настроить службу redis. Я уже писал несколько статей раньше. Вы можете обратиться к https://segmentfault.com/a/11 вот.

Библиотека Yii redis: https://github.com/yiisoft/yi…

Использование composer для установки библиотек зависимостей redis

php composer.phar require --prefer-dist yiisoft/yii2-redis

Соответствующая конфигурация web.php:

return [
    //....
    'components' => [
        'redis' => [
            'class' => 'yii\redis\Connection',
            'hostname' => 'localhost',
            'port' => 6379,
            'database' => 0,
        ],
    ]
];

На данный момент redis можно использовать для работы в Yii

Redis ~ ~ синхронизация и асинхронизация

Итак, как добиться асинхронной очереди сообщений для отправки почты?

Традиционный метод работы заключается в следующем:

  1. Вводимая Пользователем Информация о Почте

  2. Сервер получает данные, введенные пользователем, и отправляет их на почтовый сервер третьей стороны.

  3. Почтовый сервер Третьей стороны Отправляет Почту и Возвращает Результат обработки

Асинхронная обработка отправки почты:

  1. Пользователи вводят информацию, связанную с почтой

  2. Храните регистрационную информацию в очереди памяти, чтобы сообщить пользователю об успешной отправке

  3. Сервер отслеживает очередь памяти и по очереди отправляет почтовые данные в очередь памяти, которые не воспринимаются пользователем.

В чем разница между этими двумя?

Асинхронность лучше, чем синхронизация, потому что страница не блокируется и сокращает время ожидания пользователя.

Редис ~ ~ доставка почты

Принцип: Пользователи вводят информацию о почте, серверы получают информацию о входящей почте и вызывают почтовый процесс, который на самом деле является процессом присвоения атрибутов почтового класса. В это время мы можем захватить информацию о пользователе, сохранить ее в очереди, а затем по очереди прочитать информацию о почте и отправить ее.

// instantiate mail components

$mailer = Yii::$app->mailer->compose();
Mailer - > setFrom ('sender address');
Mailer - > setTo ('addressee');
Mailer - > setSubject ('Send Title');
//if ($mailer->send() && $this->reg($data, 'regbymail')) {
// Note that this itself is a direct call to the send method for sending and now override the parent method for processing with redis 
if ($mailer->queue()) {
    return true;
}

В это время мы создадим экземпляр класса mail для отправки почты. В это время мы можем захватить почтовую информацию и сохранить ее в очереди.

redis;
            if (empty($redis)) {
                throw new \yii\base\InvalidConfigException('redis not found in config.');
            }
            // 0 - 15  select 0 select 1
            // db => 1
            $mailer = Yii::$app->mailer;
            // Does the database stored in mail exist?
            if (empty($mailer) || !$redis->select($mailer->db)) {
                throw new \yii\base\InvalidConfigException('db not defined.');
            }
            // Grabbing Mail Information
            $message = [];
            $message['from'] =array_keys($this->from);
            $message['to'] =  array_keys($this->getTo());
            $message['cc'] =  array_keys($this->getCc());
            $message['bcc'] = array_keys($this->getBcc());
            $message['reply_to'] = array_keys($this->getReplyTo());
            $message['charset'] = array_keys($this->getCharset());
            $message['subject'] = array_keys($this->getSubject());
            // Get mail information and sub-information
            $parts = $this->getSwiftMessage()->getChildren();
    
            if (!is_array($parts) || !sizeof($parts)) {
                $parts = [$this->getSwiftMessage()];
            }
            foreach ($parts as $part) {
    
                if (!$part instanceof \Swift_Mime_Attachment) {
                    // Get the content type
                    switch($part->getContentType()) {
                        case 'text/html':
                            $message['html_body'] = $part->getBody();
                            break;
                        case 'text/plain':
                            $message['text_body'] = $part->getBody();
                            break;
                    }
                    if (!$message['charset']) {
                        $message['charset'] = $part->getCharset();
                    }
                }
            }
            // The serialized fetched content is stored in the queue
            
            return $redis->rpush($mailer->key, json_encode($message));
        }
    }

 The next step is to read the redis queue and send it. 
redis;
        if (empty($redis)) {
            throw new \yii\base\InvalidConfigException('redis not found in config.');
        }
        // If there is data in the queue
        if ($redis->select($this->db) && $messages = $redis->lrange($this->key, 0, -1)) {
            $messageObj = new Message;
            // Traveling through mailing lists
            foreach ($messages as $message) {
                $message = json_decode($message, true);
                if (empty($message) || !$this->setMessage($messageObj, $message)) {
                    throw new \ServerErrorHttpException('message error');
                }
                if ($messageObj->send()){
                    $redis->lrem($this->key, -1, json_encode($message));
                }
            }
        }
        return true;
    }

    // Setting up message headers
    public function setMessage($messageObj, $message) 
    {
        if (empty($messageObj)) {
            return false;
        }
        if (!empty($message['from']) && !empty($message['to'])) {
            $messageObj->setFrom($message['from'])->setTo($message['to']);
            if (!empty($message['cc'])) {
                $messageObj->setCc($message['cc']);
            }
            if (!empty($message['bcc'])) {
                $messageObj->setBcc($message['bcc']);
            }
            if (!empty($message['reply_to'])) {
                $messageObj->setReplyTo($message['reply_to']);
            }
            if (!empty($message['charset'])) {
                $messageObj->setCharset($message['charset']);
            }
            if (!empty($message['subject'])) {
                $messageObj->setSubject($message['subject']);
            }
            if (!empty($message['html_body'])) {
                $messageObj->setHtmlBody($message['html_body']);
            }
            if (!empty($message['text_body'])) {
                $messageObj->setTextBody($message['text_body']);
            }
            return $messageObj;
        }
        return false;
    }
}

До сих пор мы реализовали очередь redis для асинхронной отправки почты