PHP之 直播开发后端需要做什么——关于腾讯云直播“消息通知”的相关东西

前文已经有提到“消息通知”,那么,这个“消息通知”到底是干什么的呢?其实,从字面的意思,我们就可以知其一二,就是有什么消息了,通知你一下,只不过通知你的对象是腾讯云。

通知方式,是通过接口给你消息,这个接口,类似于微信支付的支付回调,需要你自己定义接口,以地址的形式,在腾讯云视频控制台的“功能模板”的“回调配置”,点击“加号”,会让你配置一个模板,这个模板的配置的内容有推流回调、断流回调、录制回调、截图回调,另外,还有一个“回调秘钥”,注意这个东西,它是作为腾讯云视频进入你服务器的钥匙的角色存在,所以,切勿泄露,另外,就是在代码模块,也需要通过此秘钥进行解密数据。

腾讯云“事件消息通知”文档地址:https://cloud.tencent.com/document/product/267/32744

关于这块,有几个点需要注意一下

1、公共参数里event_type,事件通知信息类型:推流事件为1;断流事件为0;录制事件为100;截图事件为200。

2、公共参数里sign,事件通知签名,计算方式:sign = MD5(key + t)。腾讯云把加密 key 和 t 进行字符串拼接后通过 MD5 计算得出 sign 值,并将其放在通知消息里,您的后台服务器在收到通知消息后可以根据同样的算法确认 sign 是否正确,进而确认消息是否确实来自腾讯云后台。

3、还有,就是消息通知,每次只返回一个流数据相关的消息,而并非返回一个流列表,所以,当同时出现多个同一事件的流,处理起来,就耐人寻味了。

4、关于可靠性上,文档里说,如果消息通知,通知到你了,但20秒未应答 或 HTTP STATUS不为200的时候,会重新发起,间隔60秒,总共3次,然而,我们通过测试,断流回调,仅回调一次,而且,并非返回{"code":0},所以,消息通知的可靠性上可能要打个问号了。

5、通知信息是以 JSON 格式进行组织的,然后放在 HTTP POST 协议体中,注意这里的 POST 格式的 ContentType 是 application/json,而不是 multipart/form-data,所以不要使用 PHP里读取表单字段的函数来读取信息。

消息回调处理代码部分

/**
 * 消息通知-事件类型
 */
const EVENT_TYPE = [ 0, 1, 100, 200 ];


/**
 * 接收post数据
 * @desc 微信是用$GLOBALS['HTTP_RAW_POST_DATA'];这个函数接收post数据的
 * @return array
 */
private function post_data()
{
    $receipt = $GLOBALS['HTTP_RAW_POST_DATA'];
    if($receipt==null){
        $receipt = file_get_contents("php://input");
    }
    return json_decode($receipt, true);
}

/**
 * 获取事件类型
 * @param array $callback
 * @return mixed
 * @time 2020-03-02
 */
private function event_type($callback)
{
    $event_type = -1;
    if(isset($callback['event_type']) && in_array($callback['event_type'], self::EVENT_TYPE)){
        $event_type = $callback['event_type'];
    }return $event_type;
}

/**
 * 安全签名 - 签名验证
 * @param array $callback
 * @return mixed
 * @time 2020-03-02
 */
private function safe_sign($callback)
{
    if(!$callback['sign'] || !$callback['t']){
        return false;
    }
    $sign = md5($this->callback_key().$callback['t']);
    return $callback['sign']!=$sign ? false : true;
}

/**
 * 配置 - 获取回调秘钥
 * @return mixed
 * @time 2020-03-04
 */
private function callback_key()
{
    $this->load->config('dict/dict_live');
    return $this->config->item('callback_key')['callback_key'];
}

/**
 * 回调处理 - 公共部分
 */
private function common_callback()
{
    $callback = $this->post_data();
    $this->safe_sign($callback);
    $event_type = $this->event_type($callback);
    return $this->switch_logic($event_type, $callback);
}

/**
 * 回调处理 - 逻辑处理分发
 * @param int $event_type
 * @param array $callback
 * @return mixed
 */
private function switch_logic($event_type, $callback)
{
    switch ($event_type) {
        case 0:
            return $this->break_stream_logic($callback);
            break;
        case 1:
            return $this->push_stream_logic($callback);
            break;
        case 100:
            return $this->live_record_logic($callback);
            break;
        case 200:
            return $this->live_screenshot_logic($callback);
            break;
    }
}

/**
 * 回调处理 - 基础
 */
private function basic()
{
    $res = $this->common_callback();
    if($res){
        return json_encode(['code'=>0]);
    }
}

/**
 * 推流、断流回调
 * @desc 消息通知有用字段:stream_id、event_time(事件产生时间)、
 * @desc push_duration(推流时长)、stream_param(推流URL参数)
 * @time 2020-03-02
 */
public function stream_callback()
{
    return $this->basic();
}

/**
 * 截图、鉴黄回调
 * @time 2020-03-03
 */
public function screeshot_callback()
{
    return $this->basic();
}

/**
 * 录制回调
 * @time 2020-03-02
 */
public function record_callback()
{
    return $this->basic();
}

/**
 * 推流回调 - 获取直播间ID
 * @desc 推流成功,记录推流状态
 * @param array $data
 * @return mixed
 */
private function room_id($data)
{
    $room_info = explode('_',$data['stream_id']);
    return $room_info[3];
}

/**
 * 断流回调 - 逻辑处理
 * @desc 如果出现断流,要记录直播断流,
 * @param array $data
 * @return mixed
 */
private function break_stream_logic($data)
{
    $this->load->service('live_room_service');
    return $this->live_room_service->sync_update_break_data($this->room_id($data), $data);
}

/**
 * 推流回调 - 逻辑处理
 * @desc 推流成功,记录推流状态
 * @param array $data
 * @return mixed
 */
private function push_stream_logic($data)
{
    $this->load->service('live_room_service');
    return $this->live_room_service->remark_push_success($this->room_id($data), $data);
}

/**
 * 录播回调 - 逻辑处理
 * @desc 录播成功,记录录播相关数据
 * @param array $data
 * @return mixed
 */
private function live_record_logic($data)
{
    $this->load->service('live_room_service');
    return $this->live_room_service->live_record_logic($this->room_id($data), $data);
}

/**
 * 截图回调 - 逻辑处理
 * @desc 截图成功,记录截图相关数据
 * @param array $data
 * @return mixed
 */
private function live_screenshot_logic($data)
{
    $this->load->service('live_room_service');
    return $this->live_room_service->live_screenshot_logic($this->room_id($data), $data);
}

/**
 * 推流回调 - 获取直播间ID
 * @desc 推流成功,记录推流状态
 * @param array $data
 * @return mixed
 */
private function room_id($data)
{
    $room_info = explode('_',$data['stream_id']);
    return $room_info[3];
}

总之,“消息通知”这块,东西不多,但是,可靠性上,有待商榷,使用的时候需要注意,但是,在某些方面,比如断流时间、原因、推流时长等的记录上,都还是有一定的可用性的,至于录播、图片鉴黄等,由于这块,业务暂时还未上,不便发表看法,后期,使用到了,在发文补充相关的东西。

好了,关于“消息通知”这块,就暂时说这么说,下篇文章,咱们来聊聊“即时通信IM”相关的东西!




The END!                                                                               2020/04/18 21:16:16
发布了74 篇原创文章 · 获赞 2 · 访问量 7375

猜你喜欢

转载自blog.csdn.net/LDR1109/article/details/105605628
今日推荐