zoukankan      html  css  js  c++  java
  • Swoole定时队列任务+消息推送

    昨晚我躺在床上,百无聊赖地翻阅 阿兰·德波顿《身份的焦虑》这本书,看到这么一段话,让我想起网络上做墙头草的键盘侠,他们喜欢贴标签,然后去简单粗暴地批评或讨好一类人,那么可以说公众的眼睛是雪亮的吗?我一直不喜欢太绝对太肯定的观点,对此我也保留怀疑,包括那些道听途说来的道理。

          公共舆论的缺陷,究其原因,在于公众不愿意将自己的观点交由理性分析进行推敲,而是将自己的观点建立在直觉、感情和习俗之上。

        我经常在早餐出门上班的时候,会在微信小程序点一份麦当劳6元实惠早餐(酸菜鸡肉粥+薯饼),然后路过的时候,顺路取餐。

        但是我最近发现,麦当劳提供了 选择取餐时间的服务。然后在对应的时间推动信息,提醒用户取餐。

    这么做有两个好处

    • 保证客户食物的新鲜

    • 工作人员可按照时间去处理订单

    emmm  我觉得这是个好的商业idea。

    在吃完这份早餐,我就想,要不用代码实现一个这个功能的demo吧。

    主要的工具

    • swoole的websocket 服务端

    • swoole的异步毫秒定时器

    • redis 的有序集合

    如果是在微信开发的话,其实调用一下微信的模板信息接口,进行消息推送。swoole_timer_after函数是一个一次性定时器,执行完成后就会销毁。此函数与PHP标准库提供的sleep函数不同,after是非阻塞的。而sleep调用后会导致当前的进程进入阻塞,将无法处理新的请求。

    使用redis 的有序集合可以的实现按照取餐时间排序的队列结构(图我自己画的),这里我怕同一秒内有多个用户下单,并发造成队列的覆盖,我选用了php获取毫秒的内置函数()

    microtime(true)//一定要加上ture才能返回浮点数据

    餐厅的工作人员可按照上面的列表来

    服务端生产队列和异步推送信息的代码实现

     1 <?php
     2 /**
     3  * Created by PhpStorm.
     4  * User: 印第安老斑鸠
     5  * Date: 2019/2/14
     6  * Time: 10:30
     7  */
     8 $server = new  swoole_websocket_server("0.0.0.0",9501);
     9 $server->set(array(
    10     'worker_num'=>2,
    11 ));
    12 $redis = new redis();
    13 $redis->connect('127.0.0.1', 6379);
    14 $server->on('open', function (SwooleWebSocketServer $server, $request) {});
    15 $server->on('message', function (SwooleWebSocketServer $server, $frame) use ($redis){
    16     //将任务安装时间丢进redis的有序集合之中(实际上要同步存进数据库)
    17     $result = $redis->zAdd('queue',microtime(true),'用户user'.time());
    18     if ($result){
    19         swoole_timer_after($frame->data,function () use($frame,$server){
    20             //做异常捕获,失败的话就通知失败
    21             try{
    22                 $str = "你好,你在".(($frame->data)/1000).'秒前的预定的套餐,请到店内柜台前拿取';
    23                 $server->push($frame->fd,$str);
    24             }catch (Exception $exception){
    25                 $server->push($frame->fd,'订单失败');
    26             }
    27         });
    28     }
    29     $server->push($frame->fd,"支付成功。请稍后,接收通知!");
    30 });
    31 $server->on('close', function ($ser, $fd) {
    32     echo "client {$fd} closed
    ";
    33 });
    34 $server->start();

    定时任务消费队列的代码实现:

    <?php
    /**
     * Created by PhpStorm.
     * User: 印第安老斑鸠
     * Date: 2019/2/15
     * Time: 12:07
     */
    $redis = new Redis();
    $redis->connect('localhost',6379);
    //3秒钟查询一次任务队列
    swoole_timer_tick(3000,function ()use($redis){
        $result = $redis->zRange('queue',0,-1);
        if($result){
            foreach ($result as $res){
                $redis->zRem("queue", $res);
                echo "队列中的".$res."的订单已经处理完毕
    ";
            }
        }else{
            echo "目前没有队列订单任务";
        }
    });

    测试结果:我创建了websocket 服务,端口是9501

    启动队列的消费的进程,结果:

    ok,就这么一个demo搞定!但并不能投放于工业生产。

    微信公众号:

  • 相关阅读:
    PHP基本的语法以及和Java的差别
    Linux 性能測试工具
    【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)
    【Oracle 集群】Oracle 11G RAC教程之集群安装(七)
    【Oracle 集群】11G RAC 知识图文详细教程之RAC在LINUX上使用NFS安装前准备(六)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之缓存融合技术和主要后台进程(四)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)
    Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
  • 原文地址:https://www.cnblogs.com/zhengweizhao/p/10410511.html
Copyright © 2011-2022 走看看