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

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

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

①先写上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给用户推送消息 防止并发重复发送)