直播视频定时控制【TCP长连接框架(WorkerMan)+键空间通知的机制 ( Keyspace Notific

时间:2022-06-01 16:40:46

标签:

一、思路梳理

同步直播视频到Redis

用户观看直播模板,点击直播按钮,检查是否有权限。

直播定时免费观看(免费观看10分钟),用户点击播放按钮开始,异步检查获取直播活动设置的免费观看时间(后台维护人员设置,Redis的hash存储信息),是否是直播。

是直播视频:判断该客户是否已经观看过了免费的20分钟时间,

没有看过,,则获取该直播视频的免费时间根据活动ID,同时设置该直播视频的过期时间(只针对该用户自己哦),返回个模板,说:这个人可以观看的。

直播视频已经看过了,则不可以继续观看哦!嘻嘻...

二、免费观看时间原理:

客户打开直播视频,立马通过消息系统(WorkerMan)获取clientId(该直播页面唯一的票据).

用户点击播放按钮时候,Ajax异步Post一个数据到服务器(clientId、liveId、openId),绑定该用户的与直播视频,根据liveId在Redis获取该活动的免费过期时间expireTime,设置自己的基本信息存储到Reids中,哈希存储格式key:liveId+clientIp.

返回给直播模板200,客户可以观看啦!

这时候就会在服务器端有一个PHP脚本(psubscribe.php)在执行,执行方式一nohub,详情观看,他负责只要有key过期。这个脚本则会收到给key过期的事件(键空间通知的机制),该过期事件会返回一个回调函数(返回值:liveId+clientIp),然后我们在这个回调函数中调用一个平台的API接口,同时传递参数过去【liveId+clientIp】,该接口接受到参数后,立马想视频直播页面通过消息机制(workerman),发送一条消息,免费时间观看完了,马上关闭视频,这时候只要在发送通知信息的时候携带一个参数状态即可。检查权限一开始就会终止掉该权限检测和关闭该视频直播的操作(JS+css样式去实现可以了),客户没办法观看了,直播窗口立即弹出。

再次点击则无法观看

刷新浏览器:点击继续观看,异步到Redis查找根据liveId和clientIp查找是否具有权限观看。

直播基本Redis信息hash存储:[后台维护人员设置或者同步Redis]

// 同步活动信息到Redis public function synchronizeLive() { $liveId = ‘L00735‘; $redis = new \Redis(); $redis->connect(‘121.141.188.202‘, 63789); $setResult = $redis->hMset($liveId, [ ‘liveId‘ => $liveId, ‘expireTime‘ => -1, //过期时间设定 ‘isLive‘ => 1, //是否是直播,1.直播,0.非直播(历史回顾) ]); if($setResult == false ) exit(‘Hmset fail‘); exit(‘Hmset success‘); }

权限设置判断代码:

/** * 活动模板页面,权限请求处理 * 这个操作应该是客户端发起的请求,当客户点击播放按钮的时候,开始该活动的免费时间(10分钟)播放,到期立马关掉 */ public function checkAuth($liveId = ‘L00735‘, $clientId = ‘‘, $openId = ‘‘) { $redis = new \Redis(); $redis->connect(‘121.41.88.209‘, 63789); //检查是否是直播,还是历史回顾视频的观看 $isLive = $redis->hGet($liveId, ‘isLive‘); $clientIp = $this->getClientIp(); if ($isLive == 1) //是直播 ,则这时候就会根据客户端的IP来判断,同一个IP则不可以继续观看啦 { $watchTag = $redis->hGet($liveId . ‘:‘ . $clientIp, ‘watchTag‘); // 该值不存在,返回:false if ($watchTag == false) { // 没有看过的 //用户给自己设置过期时间 $expireTime = $redis->hGet($liveId, ‘expireTime‘); $redis->setex($liveId . ‘:‘ . $clientIp, $expireTime, $liveId . $expireTime); $redis->hMset($liveId . ‘:‘ . $clientIp, [ ‘liveId‘ => $liveId, ‘clientIp‘ => $clientIp, //客户端IP ‘clientId‘ => $clientId, //客户观看唯一id ‘watchTag‘ => 1, //观看标记:1.已经看过,0.一次都看过 ‘openId‘ => $openId, //微信用户唯一标识 ]); //JSON 返回信息 $message = [ ‘status‘ => 200, ‘liveId‘ => $liveId, ‘clientId‘ => $clientId, ‘watchTag‘ => 0, // 0 表示没有观看过 ‘isLive‘ => $isLive, // 是直播 ]; exit(json_encode($message)); // 您是第一来,可以观看的 } else { $redisIp = $redis->hGet($liveId . ‘:‘ . $clientIp, ‘clientIp‘); if ($clientIp == $redisIp && $watchTag == 1) { $message = [ ‘status‘ => 500, ‘liveId‘ => $liveId, ‘clientId‘ => $clientId, ‘watchTag‘ => 1, // 1 表示已经观看过了 ‘isLive‘ => $isLive, // 是直播 ]; exit(json_encode($message)); //不可以继续观看了 } } } else //不是直播,你可以继续观看,但是每次都是从头开始看哦 { $watchTag = $redis->hGet($liveId . ‘:‘ . $clientIp, ‘watchTag‘); // 该值不存在,返回:false if ($watchTag == false) // 您是第一来,可以观看的 { //用户给自己设置过期时间 $expireTime = $redis->hGet($liveId, ‘expireTime‘); $redis->setex($liveId . ‘:‘ . $clientIp, $expireTime, $liveId . $expireTime); $redis->hMset($liveId . ‘:‘ . $clientIp, [ ‘liveId‘ => $liveId, ‘clientIp‘ => $this->getClientIp(), //客户端IP ‘clientId‘ => $clientId, //客户观看唯一id ‘watchTag‘ => 1, //观看标记:1.已经看过,0.一次都看过 ‘openId‘ => $openId, //微信用户唯一标识 ]); //JSON 返回信息 $message = [ ‘status‘ => 200, ‘liveId‘ => $liveId, ‘clientId‘ => $clientId, ‘watchTag‘ => 0, // 1 表示已经观看过了 ‘isLive‘ => 0, // 是直播 ]; exit(json_encode($message)); } // 您是第二次来了,自己给自己重新设置过期时间,从头开始播放吧 $expireTime = $redis->hGet($liveId, ‘expireTime‘); $redis->setex($liveId . ‘:‘ . $clientIp, $expireTime, $liveId . $expireTime); $redis->hMset($liveId . ‘:‘ . $clientIp, [ ‘liveId‘ => $liveId, ‘clientIp‘ => $this->getClientIp(), //客户端IP ‘clientId‘ => $clientId, //客户观看唯一id ‘watchTag‘ => 1, //观看标记:1.已经看过,0.一次都看过 ‘openId‘ => $openId, //微信用户唯一标识 ]); //========================统计该用户看过的次数以及刷新次数========================== $redis->incr($liveId . ‘:‘ . $this->getClientIp()); //如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键 $redis->incr(date(‘Y-m-d‘) . ‘:‘ . $clientId); //========================统计该用户看过的次数以及刷新次数========================== $message = [ ‘status‘ => 200, ‘liveId‘ => $liveId, ‘clientId‘ => $clientId, ‘watchTag‘ => 1, // 1 表示已经观看过了 ‘isLive‘ => 0, // 是直播 ]; exit(json_encode($message)); // 您是第一来,可以观看的 } }

服务器API接口: