php swoole群发邮件,Swoole实验室:3-使用Swoole批量发送邮件

建立任务

接上一节代码,编辑src/App/Mail.php文件代码,在public function onTask()方法中增加批量队列发送邮件的代码:

public function onTask(swoole_server $serv, $task_id, $from_id, $data)

{

$res['result'] = 'failed';

$req = json_decode($data, true);

$action = $req['action'];

echo date('Y-m-d H:i:s')." onTask: [".$action."].\n";

switch ($action) {

case 'sendMail': //发送单个邮件

$mailData = [

'emailAddress' => 'abc@example.com', //接收方,改成自己的邮箱可以测试接收邮件

'subject' => 'swoole实验室',

'body' => '测试This is the HTML message body.',

'attach' => '/home/swoole/public/a.jpg'

];

$this->sendMail($mailData);

break;

case 'sendMailQueue': // 批量队列发送邮件

$this->sendMailQueue();

break;

default:

break;

}

}

建立Redis队列

由于发送的邮件比较多,我们把邮件列表事先保存在Redis队列中。我们知道Redis的使用场景很多,其中就可以用它来做简单的队列。

我们在任务中调用了sendMailQueue()方法,继续在Mail.php中添加:

// 邮件发送队列

private function sendMailQueue()

{

$redis = new \Redis();

$redis->connect('127.0.0.1', 6379);

$password = '123';

$redis->auth($password);

swoole_timer_tick(1000, function($timer) use ($redis) { // 启用定时器,每1秒执行一次

$value = $redis->lpop('mailerlist');

if($value){

//echo '获取redis数据:' . $value;

$json = json_decode($value, true);

$start = microtime(true);

$rs = $this->sendMail($json);

$end = microtime(true);

if ($rs) {

echo '发送成功!'.$value.', 耗时:'. round($end - $start, 3).'秒'.PHP_EOL;

} else { // 把发送失败的加入到失败队列中,人工处理

$redis->rpush("mailerlist_err", $value);

}

}else{

swoole_timer_clear($timer); // 停止定时器

echo "Emaillist出队完成";

}

});

}

上述代码中,先尝试连接Redis,然后使用Swoole的swoole_timer_tick()函数,它是个定时器,这个函数跟js的interval()函数一样,意思是每隔一定时间执行一次,它可以定义毫秒级粒度。很显然,上述代码中,每隔1000毫秒(1秒)从Redis队列mailerlist中取出一条,即一个邮件对象,然后执行发送邮件sendMail(),当发送完所有邮件后,使用swoole_timer_clear()关闭定时器即可。定时器的间隔时间可以调整。

客户端

在客户端,我们先往Redis队列里添加邮件内容,然后向服务端发起sendMailQueue批量发邮件指令。

class Client

{

private $client;

public function __construct() {

$this->client = new swoole_client(SWOOLE_SOCK_TCP);

}

public function connect() {

if( !$this->client->connect("127.0.0.1", 9502 , 1) ) {

echo "Error: {$this->client->errMsg}[{$this->client->errCode}]\n";

}

$action = 'sendMailQueue';

$time = time();

$key = 'MYgGnQE33ytd2jDFADS39DSEWsdD24sK';

$token = md5($action.$time.$key);

$data = [

'action' => $action,

'token' => $token,

'timestamp' => $time

];

$msg = json_encode($data);

$this->client->send( $msg );

$message = $this->client->recv();

echo "Get Message From Server:{$message}\n";

}

}

$redis = new Redis();

$redis->connect('127.0.0.1', 6379);

$password = '123';

$redis->auth($password);

$arr = [];

$arr[0] = [

'subject' => '国庆大酬宾,全场1折',

'emailAddress' => 'axxxx@example.com',

'body' => '您好,国庆期间大酬宾,全场所有商品统统1折甩卖。'

];

$arr[1] = [

'subject' => '注册会员送100金币',

'emailAddress' => 'bxxxx@example.com',

'body' => '邮件内容'

];

$arr[2] = [

'subject' => '国庆大酬宾,全场1折',

'emailAddress' => 'cxxxxx@example.com',

'body' => '邮件内容2'

];

foreach ($arr as $k=>$v) {

$redis->rpush("mailerlist", json_encode($v, JSON_UNESCAPED_UNICODE));

}

$client = new Client();

$client->connect();

验证

根据上一节内容,我们应该先启动服务端,看到Swoole服务端启动好了,我们再运行客户端:

php mailClient.php

然后你可以去查看对方邮箱是否收到相关邮件。

本文中使用了redis作为简单队列,你也可以使用复杂点的队列rabbitmq。你也可以使用Crontab来做定时任务,不过它最小粒度是分钟级别的。当然对于批量发送邮件,如果你不用php的话,可以用Python或者Java,它们都有相当成熟的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值