实现场景:用户下单后通知订单,如果在3分钟后还没有接单就语音通知提醒,这里用到的是阿里云的语音通知服务,
在tp5中使用composer来安装
1、安装阿里云语音通知SDK
composer require alibabacloud/dyvmsapi-20170525
安装think-queue服务
composer require topthink/think-queue
2、think-queue的配置文件在application/extra/queue.php,内容是:
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
return [
'connector' => 'Redis', // Redis 驱动
'expire' => 60, // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null
'default' => 'default', // 默认的队列名称
'host' => '127.0.0.1', // redis 主机ip
'port' => 6379, // redis 端口
'password' => '', // redis 密码
'select' => 1, // 使用哪一个 db,默认为 db0
'timeout' => 0, // redis连接的超时时间
'persistent' => false, // 是否是长连接
];
这里需要自己安装redis,百度步骤即可。
3、消息的消费删除,建立一个文件来处理消息的逻辑
<?php
/**
* Created by PhpStorm.
* User: Admin
* Date: 2020/8/28
* Time: 14:59
*/
namespace app\api\job;
use AlibabaCloud\Client\AlibabaCloud;
use app\api\model\Remind;
use app\api\model\User;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use think\queue\Job;
class Call
{
public function fire(Job $job,$data)
{
//....这里执行具体的任务
//$data是订单提醒的id,执行任务的时候查看是否还有remind
$remind = (new Remind())->get($data);
if ($remind){
echo '执行'.$data;
//如果存在,查找用户的电话
$user = (new User())->get($remind->user_id);
// echo $user->phone;
//将用户的电话传入
if ($this->call($user->phone)){
//如果任务执行成功后记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,执行failed方法
$job->delete();
}else{
if ($job->attempts() > 3) {
//通过这个方法可以检查这个任务已经重试了几次了
$job->delete();
}
}
}else{
return;
}
// 也可以重新发布这个任务
//$job->release(60); //$delay为延迟时间
}
public function call($phone)
{
AlibabaCloud::accessKeyClient('#######', '#########')
->regionId('cn-hangzhou')
->asDefaultClient();
try {
$result = AlibabaCloud::rpc()
->product('Dyvmsapi')
// ->scheme('https') // https | http
->version('2017-05-25')
->action('SingleCallByVoice')
->method('POST')
->host('dyvmsapi.aliyuncs.com')
->options([
'query' => [
'RegionId' => "cn-hangzhou",
'CalledNumber' => $phone,
'VoiceCode' => "#########",
'CalledShowNumber' => "",
'Volume' => "100",
'PlayTimes' => "3",
'Speed' => "1",
],
])
->request();
print_r($result->toArray());
return true;
} catch (ClientException $e) {
echo $e->getErrorMessage() . PHP_EOL;
} catch (ServerException $e) {
echo $e->getErrorMessage() . PHP_EOL;
}
}
}
然后在需要创建消息的控制里,写
$isPushed = Queue::later(5,"app\api\job\Call", $data = $remind->id,"call");
5是延迟时间,$data是传递的数据,call是创建消息的名字。
4、在控制行输入命令来执行:
php think queue:work --queue call ------ 处理一个call的消息,处理完就结束
php think queue:work --daemon --queue call ---- 循环处理,可以一直监听消息
5、在linux上部署,并使用supervisor来监听消息的的处理在另一篇文章。