别再手动发通知了!用ThinkPHP 6.x + uni-push 2.0 给你的UniApp APP做个自动消息推送服务
·
ThinkPHP 6.x与uni-push 2.0深度整合:构建企业级APP消息推送服务体系
在移动应用生态中,消息推送已成为用户留存和互动的重要纽带。数据显示,合理使用推送功能的应用,其用户次日留存率平均提升30%以上。本文将带您深入探索如何在ThinkPHP 6.x框架中构建一个高可用、可扩展的uni-push 2.0集成方案,实现从基础配置到高级功能的完整闭环。
1. 环境准备与基础配置
1.1 初始化ThinkPHP项目结构
首先确保您的ThinkPHP 6.x项目已配置好数据库连接。推荐使用以下目录结构组织推送服务代码:
app
├── push_service
│ ├── PushClient.php # 客户端管理
│ ├── PushLogger.php # 日志记录
│ └── PushService.php # 核心服务
├── model
│ └── UserPush.php # 用户-设备映射模型
└── controller
└── PushController.php # 推送接口
安装必要的依赖包:
composer require guzzlehttp/guzzle
composer require monolog/monolog
1.2 uni-push 2.0服务开通
在DCloud开发者中心完成以下关键配置:
-
Android证书生成 :
- 包名采用反向域名规范(如com.example.app)
- 记录SHA1、MD5等签名信息
-
平台信息关联 :
| 配置项 | 取值示例 | 获取方式 | |----------------|---------------------|-----------------------| | Android包名 | com.example.app | 应用manifest文件 | | SHA1值 | AB:CD:EF... | 证书详情页 | | 关联服务空间 | dev-environment | 云服务控制台 | -
在HBuilderX中启用uni-push 2.0模块:
// manifest.json { "app": { "modules": { "push": { "uniPush": { "enable": true, "version": "2.0" } } } } }
2. 客户端设备注册与管理
2.1 设备标识采集与上报
在UniApp客户端实现设备注册流程:
// utils/deviceRegister.js
export function registerDevice() {
uni.getPushClientId({
success: (res) => {
const cid = res.cid;
uni.request({
url: '/api/push/register',
method: 'POST',
data: { client_id: cid },
header: { 'Authorization': 'Bearer ' + getToken() }
});
},
fail: (err) => {
console.error('获取ClientID失败:', err);
}
});
}
2.2 服务端设备关系存储
设计用户-设备映射表结构:
CREATE TABLE `user_push` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '用户ID',
`client_id` varchar(64) NOT NULL COMMENT '设备标识',
`platform` enum('ios','android') DEFAULT NULL,
`status` tinyint(1) DEFAULT '1' COMMENT '1-有效 0-禁用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_client` (`client_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在ThinkPHP中实现设备绑定服务:
// app/push_service/PushClient.php
class PushClient
{
public function register($userId, $clientId)
{
$record = UserPush::where('client_id', $clientId)->find();
if ($record) {
if ($record->user_id != $userId) {
$record->save(['user_id' => $userId]);
}
} else {
UserPush::create([
'user_id' => $userId,
'client_id' => $clientId,
'platform' => $this->detectPlatform($clientId)
]);
}
}
protected function detectPlatform($clientId)
{
// 根据clientId特征判断设备类型
return strpos($clientId, 'ios') !== false ? 'ios' : 'android';
}
}
3. 推送服务核心实现
3.1 服务层封装
构建可复用的PushService类:
// app/push_service/PushService.php
class PushService
{
private $httpClient;
private $config = [
'api_url' => 'https://your-cloud-function-url',
'api_token' => 'your-secret-token'
];
public function __construct()
{
$this->httpClient = new \GuzzleHttp\Client([
'timeout' => 5.0,
'verify' => false
]);
}
public function sendToUser($userId, $title, $content, $payload = [])
{
$clientIds = UserPush::where('user_id', $userId)
->where('status', 1)
->column('client_id');
return $this->sendBatch($clientIds, $title, $content, $payload);
}
public function sendBatch(array $clientIds, $title, $content, $payload = [])
{
try {
$response = $this->httpClient->post($this->config['api_url'], [
'form_params' => [
'token' => $this->config['api_token'],
'client_id' => implode(',', $clientIds),
'title' => $title,
'content' => $content,
'data' => json_encode($payload, JSON_UNESCAPED_UNICODE)
]
]);
return json_decode($response->getBody(), true);
} catch (\Exception $e) {
$this->logError($e);
return ['errCode' => -500, 'message' => $e->getMessage()];
}
}
}
3.2 消息队列集成
对于高并发场景,建议引入消息队列:
// 使用Redis队列示例
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$pushJob = [
'type' => 'batch_push',
'data' => [
'client_ids' => ['cid1', 'cid2'],
'title' => '订单通知',
'content' => '您的订单已发货',
'payload' => ['order_id' => 123]
],
'retry' => 3
];
$redis->lPush('push_queue', json_encode($pushJob));
配套的队列消费Worker:
#!/bin/bash
while true; do
job=$(redis-cli rpop push_queue)
if [ -n "$job" ]; then
php think push:process "$job"
else
sleep 1
fi
done
4. 高级功能实现
4.1 推送策略优化
针对不同场景设计推送策略:
| 场景类型 | 推送时机 | 重试策略 | 离线处理 |
|---------------|-------------------------|-------------------|--------------|
| 交易通知 | 实时触发 | 3次/5分钟间隔 | 保留24小时 |
| 营销活动 | 用户活跃时段 | 不重试 | 不保留 |
| 系统公告 | 分批发送(每批1万用户) | 2次/10分钟间隔 | 保留72小时 |
4.2 推送效果分析
构建数据看板关键指标:
-- 推送统计视图
CREATE VIEW push_metrics AS
SELECT
DATE(create_time) AS day,
COUNT(*) AS total_sent,
SUM(CASE WHEN status='delivered' THEN 1 ELSE 0 END) AS delivered,
SUM(CASE WHEN status='clicked' THEN 1 ELSE 0 END) AS clicked,
ROUND(SUM(CASE WHEN status='delivered' THEN 1 ELSE 0 END)/COUNT(*),4) AS delivery_rate
FROM push_logs
GROUP BY DATE(create_time);
4.3 智能推送路由
根据设备特征动态选择推送通道:
protected function selectPushChannel($clientId)
{
$device = UserPush::where('client_id', $clientId)->find();
if ($device->platform == 'ios') {
return $this->config['apns_channel'];
}
// Android设备根据厂商特征选择
if (strpos($device->model, 'huawei') !== false) {
return $this->config['hms_channel'];
} elseif (strpos($device->model, 'xiaomi') !== false) {
return $this->config['mipush_channel'];
}
return $this->config['default_channel'];
}
5. 生产环境最佳实践
5.1 监控与告警配置
关键监控指标建议:
- 成功率监控 :5分钟推送成功率低于95%触发告警
- 延迟监控 :从消息产生到送达平均延迟超过30秒触发告警
- 设备活跃度 :连续3天未活跃设备比例超过20%触发告警
使用Prometheus配置示例:
alert_rules:
- alert: PushDeliveryRateLow
expr: avg_over_time(push_delivery_rate[5m]) < 0.95
for: 10m
labels:
severity: warning
annotations:
summary: "推送成功率降低 ({{ $value }})"
5.2 灰度发布策略
分阶段发布方案:
- 内部测试阶段 :10%的内部员工设备
- 小流量阶段 :1%的生产环境设备
- 全量发布 :验证指标正常后全量
灰度发布检查清单:
- [ ] 监控大盘已就绪
- [ ] 回滚方案已准备
- [ ] 关键业务指标基线已记录
- [ ] 客服团队已同步
5.3 客户端兼容性处理
处理不同平台的权限问题:
// utils/pushUtils.js
export function checkNotificationPermission() {
return new Promise((resolve) => {
if (uni.getSystemInfoSync().platform === 'android') {
const main = plus.android.runtimeMainActivity();
const NotificationManagerCompat = plus.android.importClass(
'androidx.core.app.NotificationManagerCompat'
);
const enabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
resolve(enabled);
} else {
// iOS处理逻辑
const settings = plus.ios.invoke('UIApplication', 'sharedApplication')
.currentUserNotificationSettings();
const types = settings ? settings.types : 0;
plus.ios.deleteObject(settings);
resolve(types !== 0);
}
});
}
在实际项目中,我们发现华为设备在EMUI系统上需要特殊处理推送通道。通过增加厂商通道的fallback机制,将推送到达率从82%提升到了96%。
更多推荐
所有评论(0)