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));
posted @ 2023-01-29 09:41  郭小睿  阅读(217)  评论(0编辑  收藏  举报