异步发送邮件完整示例

异步发送邮件完整示例

大家好,又见面了,我是全栈君。

本章使用task异步进程进行邮件发送,来阐述一下以上章节提到的各个知识点。

邮件类

下载swiftmailer

composer require "swiftmailer/swiftmailer:^6.0"

Mailer.php 与 vender目录 同级

require_once __DIR__ . '/vendor/autoload.php';

class Mailer
{
    public $transport;
    public $mailer;
    /**
     * 发送邮件类 参数 $data 需要三个必填项 包括 邮件主题`$data['subject']`、接收邮件的人`$data['to']`和邮件内容 `$data['content']`
     * @param Array $data
     * @return bool $result 发送成功 or 失败
     */
    public function send($data)
    {
        $this->transport = (new Swift_SmtpTransport('smtp.qq.com', 25))
            ->setEncryption('tls')
            ->setUsername('bailangzhan@qq.com')
            ->setPassword('xxxxxx');
        $this->mailer = new Swift_Mailer($this->transport);

        $message = (new Swift_Message($data['subject']))
            ->setFrom(array('bailangzhan@qq.com' => '白狼栈'))
            ->setTo(array($data['to']))
            ->setBody($data['content']);
            
        $result = $this->mailer->send($message);

        // 释放
        $this->destroy();
        return $result;
    }
    public function destroy()
    {
        $this->transport = null;
        $this->mailer = null;
    }
}

Server

后端启动:php server.php
这里单独拆分了一个TaskRun类,并且在onWorkerStart之后进行载入,主要是为了之后的“平滑重启“

class TaskServer
{
    private $_serv;
    private $_run;

    public function __construct()
    {
        $this->_serv = new Swoole\Server("127.0.0.1", 9501);
        $this->_serv->set([
            'worker_num' => 2,
            'daemonize' => false,    //是否开启守护进程
            'log_file' => __DIR__ . '/server.log',    //守护进程调试日志
            'task_worker_num' => 2,
            'max_request' => 5000,    //防止内存泄漏
            'task_max_request' => 5000,    //防止内存泄漏
            'package_eof' => "\r\n", //设置EOF
            'open_eof_split' => true, // 自动分包
        ]);
        $this->_serv->on('Connect', [$this, 'onConnect']);
        $this->_serv->on('Receive', [$this, 'onReceive']);
        $this->_serv->on('WorkerStart', [$this, 'onWorkerStart']);
        $this->_serv->on('Task', [$this, 'onTask']);
        $this->_serv->on('Finish', [$this, 'onFinish']);
        $this->_serv->on('Close', [$this, 'onClose']);
    }
    public function onConnect($serv, $fd, $fromId)
    {
    }
    public function onWorkerStart($serv, $workerId)
    {
        require_once __DIR__ . "/TaskRun.php";
        $this->_run = new TaskRun;
    }
    public function onReceive($serv, $fd, $fromId, $data)
    {
        $data = $this->unpack($data);
        $this->_run->receive($serv, $fd, $fromId, $data);
        // 投递一个任务到task进程中
        if (!empty($data['event'])) {
            $serv->task(array_merge($data , ['fd' => $fd]));
        }
    }
    public function onTask($serv, $taskId, $fromId, $data)
    {
        $this->_run->task($serv, $taskId, $fromId, $data);
    }
    public function onFinish($serv, $taskId, $data)
    {
        $this->_run->finish($serv, $taskId, $data);
    }
    public function onClose($serv, $fd, $fromId)
    {
    }
    /**
    * 对数据包单独处理,数据包经过`json_decode`处理之后,只能是数组
    * @param $data
    * @return bool|mixed
    */
    public function unpack($data)
    {
        $data = str_replace("\r\n", '', $data);
        if (!$data) {
            return false;
        }
        $data = json_decode($data, true);
        if (!$data || !is_array($data)) {
            return false;
        }
        return $data;
    }
    public function start()
    {
        $this->_serv->start();
    }
}
$reload = new TaskServer;
$reload->start();

TaskRun 业务类

当此处修改了代码后,可以进行平滑重启,因为他是在Server端的onWorkerStart之后加载的文件。

require_once ('./Mailer.php');
class TaskRun
{
    public function receive($serv, $fd, $fromId, $data)
    {
    }
    public function task($serv, $taskId, $fromId, $data)
    {
        try {
            switch ($data['event']) {
                case 'send-mail':
                    $mailer = new Mailer;
                    $result = $mailer->send($data);
                    break;
                default:
                    break;
            }
            return $result;
        } catch (\Exception $e) {
            throw new \Exception('task exception :' . $e->getMessage());
        }
    }
    public function finish($serv, $taskId, $data)
    {
        return true;
    }
}

Client

client加了eof,为了防止粘包,通过网址访问该程序

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);

$client->connect('127.0.0.1', 9501) || exit("connect failed. Error: {$client->errCode}\n");

$data = [
    'event' => 'send-mail',
    'to' => '5566***@qq.com',
    'subject' => 'just a test',
    'content' => 'This just a test.',
];

$client->send(togetherDataByEof($data));    //发送数据给服务端

$client->close();   //关闭连接

/**
 * 数据末尾拼接EOF标记
 * @param Array $data 要处理的数据
 * @return String json_encode($data) . EOF
 */
function togetherDataByEof($data)
{
    if (!is_array($data)) {
        return false;
    }
    return json_encode($data) . "\r\n";
}

异步发送邮件完整示例

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111876.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • pycharm全局搜索代码_linux全局搜索字符串

    pycharm全局搜索代码_linux全局搜索字符串参考链接实测好用!我改为Ctrl+Shift+G也有冲突,把G随便换成其它无冲突的字母就可用了!

  • mac pycharm永久激活_mac apfs 格式

    mac pycharm永久激活_mac apfs 格式问题Pycharm使用秘钥登录服务器需要RAS格式的秘钥,然而我们在MAC上直接用ssh-keygen生成的秘钥并不满足格式要求,会发生如下报错。***iscorruptorhasunknownformat.OnlySSH2keysinOpenSSHformat(DSA,RSA,ECDSA)orPuTTYPrivateKey*.ppkkeysaresupported.Errormessage:invalidprivatekey:[B@5233fcc0

  • hexo博客主题推荐_wordpress社交主题

    hexo博客主题推荐_wordpress社交主题crystalBlog上篇hexo博客搭建及主题优化(一)主题优化二21.网站log设置主题目录下的_config.yml配置文件中:#配置网站favicon和网站LOGO##本地#favicon:/favicon.png#logo:/medias/logo.png#此处我用的CDN,也可以使用本地文件favicon:https://cdn.jsdelivr.net/gh/guixinchn/image/blog/favicon.pnglogo:https://cdn

  • MySQL数据库备份的几种方式

    MySQL数据库备份的几种方式MySQL备份的几种方式最近一直想写点博客,但是不知道写什么,感觉自己最近的知识没有什么增加,今天想到了一篇可以写的博客。以前试过根据data文件夹备份MySQL,但是从来没有成功过,前几天帮助朋友还原MySQL,终于成功的将备份的data文件夹还原成功了。MySQL数据库算是常用的数据库中最好使用的数据库了,对于备份的操作也不例外。所以今天分享一下MySQL数据库的备份的几种方式。方

  • webstorm激活码3月最新在线激活

    webstorm激活码3月最新在线激活,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • vs生成sln文件_VS二进制文件

    vs生成sln文件_VS二进制文件VisualStudio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件。为解决方案资源管理器提供显示管理文件的图形接口所需的信息,从而在每次继续开发任务时,不会因开发环境而分散精力;*.sln:(VisualStudio.Solution)通过为环境提供对项目、项目项和解决方案项在磁盘上位置的引用,可将它们组织到解决方案…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号