thinkphp+redis实现百万微信订阅消息推送
需求
最近做东西,遇到一个需求:房间开奖后,推送结果到客户微信。
因房间参与人数过多,如果去批量去请求微信接口,会导致http请求超时。所以采用以下方法实现以上需求。
Thinkphp5 使用命令行模式运行--订阅端
创建自定义命令行
第一步,配置command.php文件,目录在application/command.php
<?php
return [
'app\home\command\Test',
];
第二步,建立命令类文件,新建application/home/command/Subscribe.php
<?php
namespace app\common\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\cache\driver\Redis;
/**
* Class Intive
*
* @package app\common\command
*/
class Subscribe extends Command
{
private $appid = 'xxxxx'; //微信支付申请对应的公众号的APPID
private $appKey = 'xxxxx'; //微信支付申请对应的公众号的APP Key
protected function configure()
{
$this->setName('subscribe')
// 配置一个参数
->setDescription('发送开奖订阅消息');
}
protected function execute(Input $input, Output $output)
{
ini_set('default_socket_timeout', -1); //不超时
$redis = new Redis();
$redis->pconnect('localhost', 6379, 0);
$redis->subscribe(['subscribe_room_player'], function ($redis, $channel, $msg) {
foreach (json_decode($msg, true) as $k => $v) {
// echo $v['openid'];
$openid = $v['openid'];
$free_room_id = $v['free_room_id'];
$template_id = "CpntvcAc0Hnnub6ByC1fdzCHQkn7l3xoI3tbvkXHRGc";
//消息发送的格式
$template = "{
\"touser\": \"{$openid}\",
\"template_id\": \"{$template_id}\",
\"page\":\"http:\/\/yms.guoxiaorui.cn\/#\/ArenaRoom?id={$free_room_id}\",
\"lang\":\"zh_CN\",
\"data\": {
\"thing1\": {
\"value\": \"开奖时间到!\"
},
\"name2\": {
\"value\": \"圆梦赏官方\"
},
\"date3\": {
\"value\": \"" . date("Y/m/d H:i:s") . "\"
},
\"thing4\": {
\"value\": \"中奖后,记得联系客服哦!\"
} ,
\"thing5\": {
\"value\": \"点击卡片,即可查看中奖结果~\"
}
}
}";
if (empty(cache('accessToken'))) {
$access_token = $this->getAccessToken($this->appid, $this->appKey); // 传入微信公众号信息
cache('accessToken', $access_token, 7200);
} else {
$access_token = cache('accessToken');
}
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token={$access_token}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $template);
$output = curl_exec($ch);
curl_close($ch);
var_dump($output);
}
});
}
protected function getAccessToken($appid, $appKey)
{
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $appKey;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res = curl_exec($curl);
$res = json_decode($res, true);
return $res['access_token'];
}
}
第三步,运行
php think subscribe
发布端
$player_list = [['openid' => 'oXBviwyc7xNlLN-Suji3YiL40bRc','free_room_id'=>'63']];
$redis = new Redis();
$redis->publish('subscribe_room_player', json_encode($player_list));