PHP多线程Swoole实现微信公众号模板消息的主动推送

服务端代码:

<?php

$server = new Swoole\Server('127.0.0.1', 9503);

$server->set([
    'worker_num' => 1,
    'daemonize' => false,  // 守护进程,开启后,关闭SSH面也可进行
    'log_file' => 'swoole_task.log',
    'task_worker_num' => 200       // task进程数量
]);

// 主进程启动时回调函数
$server->on('start', function ($server) {
    echo "服务端启动:" . date("Y-m-d H:i:s") . PHP_EOL;
});

// 收到信息时执行
$server->on('receive', function ($server, $fd, $reactor_id, $data) {

    echo "收到数据" . PHP_EOL;

    $data = json_decode($data, true);

    $pdo = new PDO('mysql:host=localhost;dbname=数据库名', '用户名', '数据库密码');
    $res = $pdo->query("SELECT openid FROM `表名`");
    while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
        $touser[] = $row['openid'];
    }
    $touser = array_reverse($touser);

    foreach ($user as $key => $value) {
        $info = [
            'touser' => '粉丝Openid',
            'template_id' => '公号消息推送模版ID',
            'url' => 'www.baidu.com',
            'data' => [
                'first' => [
                    'value' => '标题',
                    'color' => '#173177',
                ],
                'keyword1' => [
                    'value' => '项目名称',
                    'color' => '#CC3399',
                ],
                'keyword2' => [
                    'value' => '最新状态',
                    'color' => '#CC3399',
                ],
                'keyword3' => [
                    'value' => date('Y年m月d日 H:i:s'),
                    'color' => '#CC3399',
                ],
                'remark' => [
                    'value' => '备注',
                    'color' => '#FF0000',
                ]
            ]
        ];
        $info = json_encode($info);
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $data['access_token'];
        // 投递异步任务
        $server->task([
            'url' => $url,
            'info' => $info,
            'id' => $data['id'],
        ]);
        // 记录到文件
        swoolelogs(date('Y-m-d H:i:s') . " [{$value}]\r\n");
    }
});

// 处理异步任务
$server->on('task', function ($server, $task_id, $reactor_id, $data) {
    echo "开始处理异步";
    $res = httpRequest($data['url'], $data['info']);

    if ($res) {
        $pdo = new PDO('mysql:host=localhost;dbname=数据库名', '数据库密码', 'keGfXC2Zf7ASeMGy');
        try {
            // 推送成功条数
            $res = $pdo->exec('UPDATE `txlt_send` SET `success_num`=`success_num`+1 WHERE `id` = ' . $data['id']);
        } catch (Exception $e) {
            $pdo->rollBack();
            echo "Failed: " . $e->getMessage();
        }
    }

    echo $res . PHP_EOL;

    $server->finish('请求回调方法');
});

// 异步任务完成通知回调
$server->on('finish', function ($server, $task_id, $data) {
    echo "完成回调" . date("Y-m-d H:i:s") . ':' . $data;
});

// 建立连接
$server->on('connect', function ($server, $fd, $reactor_id) {
    echo "客户端连接成功:" . date("Y-m-d H:i:s") . PHP_EOL;
});

// 关闭连时回调函数
$server->on('close', function ($server, $fd, $reactor_id) {
    echo "客户端关闭连接:" . date("Y-m-d H:i:s") . PHP_EOL;
});

$server->start();

function httpRequest($url, $data)
{
    $options = array(
        'http' => array(
            'method' => 'POST',
            'header' => 'Content-type:application/x-www-form-urlencoded',
            'content' => $data,
            // 'protocol_version' => 1.1,
            // 'header' => [
            // 'Connection: close',
            // ],
            'timeout' => 2 // 超时时间(单位:s)
        )
    );
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    return $result;
}

function swoolelogs($str)
{
    // 记录到文件
    if (($fp = fopen(__DIR__ . '/swoole_task_logs.txt', 'a+')) !== false) {
        fputs($fp, $str);
        fclose($fp);
    }
}

客户端:

<?php

client();

/**
 * 请求服务端
 * $params 消息推送模版数据
 * $id     推送记录ID
 */
function client($params, $id)
{
    $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
    $ret = $client->connect("127.0.0.1", 9503);

    // 可传递参数,这里获取缓存好的access_token
    $sendData = [
        'access_token' => curl_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的app_id&secret=你的app_secret')['access_token'],
        'data' => $params,
        'id' => $id
    ];

    if (empty($ret)) {
        shell_exec("echo '连接swoole服务器失败'>>");
    } else {
        return $client->send(json_encode($sendData));
        // $res = $client->send(json_encode($sendData));
        // var_dump($ret);
    }

}

function curl_get($url)
{
    // 初始化
    $curl = curl_init();
    // 设置抓取的url
    curl_setopt($curl, CURLOPT_URL, $url);
    // 设置头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, 0);
    // 设置获取的信息以文件流的形式返回,而不是直接输出。
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    // 执行命令
    $data = curl_exec($curl);
    // 关闭URL请求
    curl_close($curl);

    if (isset(json_decode($data, true)['errcode'])) {
        return json_decode($data, true);
    } else {
        // 返回数据
        return json_decode($data, true);
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

withoutfear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值