美文网首页
php给用户推送消息 防止并发重复发送

php给用户推送消息 防止并发重复发送

作者: a逗号 | 来源:发表于2017-12-28 17:52 被阅读0次

            随着微信时代的到来,有时商家会利用微信公众号会给用户发送模板消息,但是粉丝太多,同事发送服务器会受不了,又不能保证每个用户都能接收到,肿么办。。。

            大神们别着忙,逗号来给您支招。

    ①先写上php

    ini_set('display_errors', 'On');

    error_reporting(30719);

    ignore_user_abort();

    set_time_limit(0);

    //define('IN_MOBILE', true);

    require '../../../../framework/bootstrap.inc.php';

    require_once IA_ROOT . '/addons/match_making/core/common/defines.php';

    require_once PATH_CORE . 'common/autoload.php';

    Func_loader::core('global');

    global $_W, $_GPC;

    //return;

    $sets = pdo_fetchall('select distinct uniacid from ' . tablename(PDO_NAME . 'setting'));

    foreach ($sets as $set) {

    $_W['uniacid'] = $set['uniacid'];

    if (empty($_W['uniacid']) || $_W['uniacid'] == -1) {

    continue;

    }

    //查询没有推送完毕的消息,因为推送不会很频繁每次只查询一个即可

    $time = TIMESTAMP - 86400; //目前只选择推送刚刚发布的消息

    $sql = "SELECT * FROM " . tablename(PDO_NAME . 'message')

    . " WHERE uniacid = '{$_W['uniacid']}'"

    . " AND `status` = 1 AND `ispush` =1 AND (`ispushed` = 0 OR `ispushed` = 1) "

    . " AND `updatetime` > $time "

    . " ORDER BY id desc";

    $message = pdo_fetch($sql);

    //存在没有推送或正在推送的消息

    if (!empty($message)) {

    //没有推送过的消息

    if ($message['ispushed'] == 0) {

    //标记为正在推送

    $result = pdo_update(PDO_NAME . 'message', array('ispushed' => 1), array('id' => $message['id'], 'ispushed' => 0));

    //如果标记成功,将所有用户的信息插入到临时表,等待推送

    if ($result) {

    //所有用户的openid

    $sql = "SELECT openid FROM " . tablename(PDO_NAME . 'member')

    . " WHERE uniacid = '{$_W['uniacid']}'"

    . " AND `follow` = 1 ";

    //                    . " AND `istest` =1 ";

    $openids = pdo_fetchall($sql);

    if (!empty($openids)) {

    $insert = "INSERT INTO " . tablename(PDO_NAME . 'message_push') . " (`uniacid`, `mid`, `openid`) VALUES ";

    foreach ($openids as $openid) {

    $insert .= "({$_W['uniacid']}, {$message['id']}, '{$openid[openid]}'),";

    }

    $insert = rtrim($insert, ',');

    $insert .= ';';

    pdo_query($insert);

    }

    }

    }

    /**

    * 给用户推送消息流程 防止并发重复发送

    * 1. 每一个进程(每次请求时)生成唯一一个 updateid

    * 2. 将updateid赋予等待推送的用户

    * 3. 选择赋予updateid成功的用户,进行推送(推送完毕后删除记录,防止push表日益变大)

    * 4. 如果没有等待推送的用户,说明已经推送完毕,标记消息为推送完成

    */

    $updateid = random(10, true);

    $limit = 10;

    $sql = "UPDATE " . tablename(PDO_NAME . 'message_push') . " SET updateid = $updateid "

    . " WHERE mid = :mid  AND updateid = 0 limit $limit ";

    $result = pdo_query($sql, array(':mid' => $message['id']));

    if ($result) {

    $sql = "SELECT id,openid FROM " . tablename(PDO_NAME . 'message_push') . " WHERE updateid = $updateid limit $limit";

    $pushlist = pdo_fetchall($sql, array(), 'id');

    foreach ($pushlist as $push) {

    //                usleep(250000);

    //                $input['time'] = date('Y-m-d H:i:s', time());

    //                $input['openid'] = $push['openid'];

    Message::todo($push['openid'], $message);

    Util::wl_log('message_send', PATH_DATA . 'task/', $input);

    }

    //删除已经发送完毕的记录

    $ids = array_keys($pushlist);

    $ids_str = implode(',', $ids);

    $sql = "DELETE FROM " . tablename(PDO_NAME . 'message_push') . " WHERE id IN($ids_str)";

    pdo_query($sql);

    } else {

    //标记为推送完成

    pdo_update(PDO_NAME . 'message', array('ispushed' => 2), array('id' => $message['id']));

    }

    }

    }

    ②然后在后台或者用户端写上js,来执行这个程序

    if(typeof(jQuery)=='undefined'){

    }else{

    setInterval(function () {

    $.ajax({

    url: "{php echo mobile_url('common/runTask')}",

    cache: false

    })

    }, 10000);

    }

    这样就ok了!!!

    相关文章

      网友评论

          本文标题:php给用户推送消息 防止并发重复发送

          本文链接:https://www.haomeiwen.com/subject/iqddixtx.html