HeartbeatController.class.php
3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
/**
* 心跳 刷新在线存活状态
* Created by PhpStorm.
* User: zhoutao
* Date: 2018/2/1
* Time: 下午4:38
*/
namespace Api\Controller\Room;
use Common\Common\Constant;
use Common\Common\Order;
use Common\Service\MainService;
use Common\Service\StudioService;
use Org\Util\DistributedRedisLock;
use VcySDK\Enterprise;
use VcySDK\Service;
class HeartbeatController extends AbstractController
{
/**
* Heartbeat
* @author zhoutao
* @desc 心跳 刷新在线存活状态
* @param Int lm_id:true:1 直播活动ID
* @return array
[
'onlineTotal' => 12 // 直播当前在线人数
]
*/
public function index()
{
$lmId = I('post.lm_id');
if (empty($lmId)) {
E('_EMPTY_LIVE_ID');
}
$redis = new \Redis();
$redis->connect(cfg('REDIS_HOST'), cfg('REDIS_PORT'));
if (cfg('REDIS_PWD')) {
$redis->auth(cfg('REDIS_PWD'));
}
// 获取当前在线人数
$this->_result['onlineTotal'] = count($redis->keys('Live_' . $lmId . '_USER_*'));
// 是否在在线人数内 不计算峰值
$userInRedisKey = 'Live_' . $lmId . '_USER_' . $this->uid;
if ($redis->exists($userInRedisKey)) {
// 刷新存活时长
$redis->set($userInRedisKey, '', Constant::ONLINE_SURVIVAL_TIME);
} else {
$this->_result['onlineTotal'] ++;
// 不存在 当成新人计算
// 获取直播活动详情
$mainServ = new MainService();
$mainDetail = $mainServ->get($lmId);
// 如果已经结束了 不扣减并发人数
if ($mainDetail['live_status'] == Constant::LIVE_STATUS_OVER) {
// 算进在线人数内
$redis->set($userInRedisKey, '', Constant::ONLINE_SURVIVAL_TIME);
return true;
}
// 获取锁
$redLock = new DistributedRedisLock([$redis], 500, 10);
$lock = $redLock->lock('Live_' . $lmId . '_Lock_Update_Peak', 1000);
if (!$lock) {
E('_ERR_PLEASE_TRY_AGAIN_LATER');
}
// 获取峰值
$redisKeyNamePeak = 'Live_' . $lmId . '_PEAK';
$peakMemberNum = $redis->get($redisKeyNamePeak) ?: $mainDetail['online_peak'];
// 在线人数超过峰值
if ($this->_result['onlineTotal'] > $peakMemberNum) {
$studioServ = new StudioService();
$studioDetail = $studioServ->get_by_conds(['lm_id' => $mainDetail['lm_id']]);
// isStandard -- 企业是否使用标准产品 : 0:非标准, 1:标准产品
$sdk = new Enterprise(Service::instance());
$epDetail = $sdk->detail();
if (1 == $epDetail['isStandard']) {
// 扣减并发人数
$orderUtil = new Order();
$deductionsSuccess = $orderUtil->LiveCaseExpend([
'liveCastId' => $studioDetail['stream_id'],
'lcelSpendAmout' => 1
]);
\Think\Log::record('扣减结果:::' . var_export($deductionsSuccess, true));
// 扣减失败
if (!$deductionsSuccess) {
E('_ERR_PLEASE_TRY_AGAIN_LATER');
}
}
// 单个用户进来只会增加一个峰值
$redis->incr($redisKeyNamePeak);
$redis->expire($redisKeyNamePeak, Constant::PEAK_SURVIVAL_TIME);
// 增加峰值
$mainServ->update($lmId, ['online_peak = online_peak + ?' => 1]);
}
// 释放锁
$redLock->unlock($lock);
// 算进在线人数内
$redis->set($userInRedisKey, '', Constant::ONLINE_SURVIVAL_TIME);
}
return true;
}
}