redis实现消息队列

15 篇文章 0 订阅
3 篇文章 0 订阅

最近看了一个微信公众号,我刚关注就每隔一会就会给我发消息,然后我也想试着做做呗

laravel开发的用的任务调度+crontab

<?php

namespace App\Console\Commands;

use App\Model\weixin\WxMessageInfoModel;
use App\Model\weixin\WxSendMessageModel;
use App\Model\weixin\WxUserModel;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;


class sendText extends Command
{
    protected $appid=""; //公众号APPID
    protected $appsecret=""; //公众号秘钥
    protected $WxMessageInfo; //模板内容表
    protected $WxSendMessage; //发送记录表
    protected $WxUser;        //微信用户
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'sendText';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * sendText constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->WxSendMessage= new WxSendMessageModel(); //发送记录
        $this->WxMessageInfo= new WxMessageInfoModel(); //模板内容
        $this->WxUser       = new WxUserModel();        //微信用户
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->action_send();
    }
    public function action_send(){
        //获取发送用户openid
        $user_info=$this->WxUser->get()->toArray();
        //获取发送内容
        $message=$this->WxMessageInfo->get()->toArray();
        //redis入队
        if(Redis::exists('list') != 1){
            foreach ($message as $k=>$v){
                Redis::rpush('list',$v['message']);
            }
        }
        //redis出队
        $un_send_message=Redis::lpop('list');
        //实现发送
        foreach ($user_info as $k=>$v){
            //查看是否已经发送
            //刚注册用户
            //$send_info=$this->WxSendMessage->where("userid",$v['id'])->get()->toArray();
            if($v['status']==1){
                //发送中
                $insert=[
                    'send_time'=>time(),
                    'userid'=>$v['id'],
                    'status'=>2
                ];
                $insert_send=$this->storeRecord($insert,$this->WxSendMessage);
                if($insert_send){
                    $send_message=[
                        'openid'=>$v['openid'],
                        'data'=>$un_send_message
                    ];
                    //发送
                    $send=$this->send_text($send_message);
                    Log::info($send);
                    //发送成功
                    if($send['errcode']==0 && $send['errmsg']=='ok'){
                        //修改发送状态
                        $update=[
                            'send_time'=>time(),
                            'userid'=>$v['id'],
                            'status'=>1
                        ];
                        $this->WxSendMessage->where("userid",$v['id'])->update($update);
                    }
                }
            }
        }
    }

    /**
     * @param $send_message
     * @return mixed
     */
    public function send_text($send_message){
        unset($_SESSION);
        //获取Access_token
        $Access_token=$this->get_wx_access_token();
        //请求地址
        $url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$Access_token;
        //组装接口Array
        $array=[
            "touser"=>$send_message['openid'], //用户的openid
            "text"=>["content"=>$send_message['data']],
            "msgtype"=>"text"
        ];
//        将array->json()
        $postJson=json_encode($array,JSON_UNESCAPED_UNICODE);
        //调用url
        $send=$this->my_curl_wx_api($url,'POST',$postJson);
        return $send;
    }
    public function get_wx_access_token(){
        //将access_token存在session/cookie中
        //如果access_token在session中并没有过期
        if (isset($_SESSION['access_token']) && $_SESSION['expire_time'] > time()) {
            return $_SESSION['access_token'];
        }
        //如果access_token不存在或者已经过期,重新获取access_token
        else {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appid . "&secret=" . $this->appsecret;
            $arr = $this->my_curl_wx_api($url);
            //存到session中
            $access_token             = $arr['access_token'];
            $_SESSION['access_token'] = $arr['access_token'];
            $_SESSION['expire_time']  = time() + 7200;
            return $access_token;
        }
    }
    /**
     * @param $url
     * @param string $type
     * @param array $data
     * @return mixed
     * 接口请求
     */
    protected function my_curl_wx_api($url, $type = 'POST', $data = array()){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false);
        curl_setopt($ch, CURLOPT_HEADER,0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        if($data){
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        //curl_setopt ( $ch, CURLOPT_SAFE_UPLOAD, false);
        $result = curl_exec($ch);
        curl_close($ch);
        return json_decode($result, true);
    }
    public function storeRecord(array $parmes,$object){
        if(empty($parmes)){
            return false;
        }
        foreach($parmes as $k =>$v){
            $object->$k = $v;
        }
        return $object->save();
    }
}
//关于这个文件放在哪。可以去看我的laravel任务调度那篇文章

laravel任务调度
laravel原本是这样执行的php artisan schedule:run,但是没有达到队列的效果
所以我们再crontab -e 中放入*/1 * * * * php /home/wwwroot/laravel_admin/artisan schedule:run >> /dev/null 2>&1就可以了
两篇文章结合起来就OK了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值