tencent cloud

实时音视频

旁路转推回调

下载
聚焦模式
字号
最后更新时间: 2024-11-06 18:24:41
服务端转推回调支持将您使用 旁路转推 REST API 产生转推 CDN 的事件,以 HTTP/HTTPS 请求的形式通知到您的服务器。您可以向腾讯云提供相关的配置信息来开通该服务。

配置信息

Tencent RTC 控制台 支持自助配置回调信息,配置完成后即可接收事件回调通知。



注意:
您需要提前准备以下信息:
必要项:接收回调通知的 HTTP/HTTPS 服务器地址。
可选项:计算签名的 密钥 key,由您自定义一个最大32个字符的 key,以大小写字母及数字组成。

超时重试

事件回调服务器在发送消息通知后,5秒内没有收到您的服务器的响应,即认为通知失败。首次通知失败后会立即重试,后续失败会以10秒的间隔继续重试,直到消息存续时间超过1分钟,不再重试。

事件回调消息格式

事件回调消息以 HTTP/HTTPS POST 请求发送给您的服务器,其中:
字符编码格式:UTF-8。
请求:body 格式为 JSON。
应答:HTTP STATUS CODE = 200,服务端忽略应答包具体内容,为了协议友好,建议客户应答内容携带 JSON: {"code":0}。
包体示例:下述为“转推时间组-CDN 推流正在进行”事件的包体示例。
{ "EventGroupId": 4, "EventType": 401, "CallbackTs": 1622186275913, "EventInfo": { "RoomId": "xx", "RoomType": 1, "EventTsMs": 1622186275913, "UserId": "xx", "TaskId": "xx", "Payload": { "Url": "rtmp://tencent-url/xxxx" "Status": 2 /表示该转推任务正在向腾讯云CDN推流/ } } }

参数说明

回调消息参数

事件回调消息的 header 中包含以下字段:
字段名
值
Content-Type
application/json
Sign
签名值
SdkAppId
sdk application id
事件回调消息的 body 中包含以下字段:
字段名
类型
含义
EventGroupId
Number
事件组ID,混流转推事件固定为4
EventType
Number
回调通知的事件类型
CallbackTs
Number
事件回调服务器向您的服务器发出回调请求的 Unix 时间戳,单位为毫秒
EventInfo
JSON Object

事件组 ID

字段名
值
含义
EVENT_GROUP_CLOUD_PUBLISH
4
转推事件组

事件类型

字段名
值
含义
EVENT_TYPE_CLOUD_PUBLISH_CDN_STATUS
401
云端转推 CDN 状态回调

事件信息

字段名
类型
含义
RoomId
String/Number
房间名(类型与客户端房间号类型一致)
RoomType
Number
0表示数字房间号,1表示字符串房间号
EventMsTs
Number
事件发生的 Unix 时间戳,单位为毫秒
UserId
String
发起任务时指定的伴生机器人的用户 ID(AgentParams.UserId)
TaskId
Number
任务 ID
Payload
JSON Object
事件的详细信息

Payload(详细信息)

字段名
值
含义
Url
String
推流的目的 URL 地址
Status
Number
ErrorCode
Number
错误码
ErrorMsg
String
错误信息

转推状态

字段名
值
含义
回调频率
PUBLISH_CDN_STREAM_STATE_IDLE
0
推流未开始或已结束
仅回调1次
PUBLISH_CDN_STREAM_STATE_CONNECTING
1
正在连接 TRTC 服务器和 CDN 服务器
每5秒回调1次,60秒超时后不再回调
PUBLISH_CDN_STREAM_STATE_RUNNING
2
CDN 推流正在进行
仅回调1次
PUBLISH_CDN_STREAM_STATE_RECOVERING
3
TRTC 服务器和 CDN 服务器推流中断,正在恢复
每5秒回调1次,60秒超时后不再回调
PUBLISH_CDN_STREAM_STATE_FAILURE
4
TRTC 服务器和 CDN 服务器推流中断,且恢复或连接超时
仅回调1次
PUBLISH_CDN_STREAM_STATE_DISCONNECTING
5
正在断开 TRTC 服务器和 CDN 服务器
仅回调1次

转推状态推荐处理

状态
处理方法
PUBLISH_CDN_STREAM_STATE_IDLE
表示 URL 移除成功,无需处理。
PUBLISH_CDN_STREAM_STATE_CONNECTING
表示 URL 正在连接中,每隔5s回调一次,直到连接成功回调PUBLISH_CDN_STREAM_STATE_RUNNING,或者60s后回调PUBLISH_CDN_STREAM_STATE_FAILURE。您可以在收到PUBLISH_CDN_STREAM_STATE_FAILURE的时候替换有问题的 URL,调用UpdatePublishCdnStream更新 Publish 参数。
如果您的业务对时间比较敏感,可以在收到2个或以上的PUBLISH_CDN_STREAM_STATE_CONNECTING回调后,替换有问题的 URL,调用UpdatePublishCdnStream更新 Publish 参数。
PUBLISH_CDN_STREAM_STATE_RUNNING
表示 URL 推流成功,无需处理。
PUBLISH_CDN_STREAM_STATE_RECOVERING
表示推流过程发生了中断,正在重连中,每隔5s回调一次,直到重连成功回调PUBLISH_CDN_STREAM_STATE_RUNNING,或者60s后回调PUBLISH_CDN_STREAM_STATE_FAILURE。通常为网络抖动,无需处理。
如果PUBLISH_CDN_STREAM_STATE_RECOVERING和PUBLISH_CDN_STREAM_STATE_RUNNING短时间内交替出现,您需要检查下是否存在多任务使用相同的推流 URL 。
PUBLISH_CDN_STREAM_STATE_FAILURE
表示推流 URL ,在60s内建连失败或者恢复推流失败,此时您可以替换有问题的 URL ,调用UpdatePublishCdnStream更新 Publish 参数。
PUBLISH_CDN_STREAM_STATE_DISCONNECTING
表示,正在移除推流 URL ,移除成功后,会回调PUBLISH_CDN_STREAM_STATE_IDLE,无需处理。

基本回调转移示例

发起转推/新增转推地址到转推成功的事件转移 PUBLISH_CDN_STREAM_STATE_CONNECTING -> PUBLISH_CDN_STREAM_STATE_RUNNING
停止转推/删除转推地址到停止转推成功的事件转移 PUBLISH_CDN_STREAM_STATE_RUNNING -> PUBLISH_CDN_STREAM_STATE_DISCONNECTING -> PUBLISH_CDN_STREAM_STATE_IDLE
转推过程中,链接失败到重试链接成功的事件转移 PUBLISH_CDN_STREAM_STATE_RUNNING -> PUBLISH_CDN_STREAM_STATE_RECOVERING -> PUBLISH_CDN_STREAM_STATE_RUNNING
转推过程中,链接失败到重试链接超时失败的事件转移 PUBLISH_CDN_STREAM_STATE_RUNNING -> PUBLISH_CDN_STREAM_STATE_RECOVERING -> PUBLISH_CDN_STREAM_STATE_FAILURE->PUBLISH_CDN_STREAM_STATE_IDLE
注意:
推流回调有可能会乱序到达您的回调服务器,此时您需要根据 EventInfo 中的 EventMsTs 做事件排序,如果您只关心 URL 最新状态,可以忽略后续到达的过期事件。

计算签名

签名由 HMAC SHA256 加密算法计算得出,您的事件回调接收服务器收到回调消息后,通过同样的方式计算出签名,相同则说明是腾讯云的实时音视频的事件回调,没有被伪造。签名的计算如下所示:
//签名 Sign 计算公式中 key 为计算签名 Sign 用的加密密钥。
Sign = base64(hmacsha256(key, body))
注意:
body 为您收到回调请求的原始包体,不要做任何转化,示例如下:
body="{\\n\\t\\"EventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t103,\\n\\t\\"CallbackTs\\":\\t1615554923704,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t12345,\\n\\t\\t\\"EventTs\\":\\t1608441737,\\n\\t\\t\\"UserId\\":\\t\\"test\\",\\n\\t\\t\\"UniqueId\\":\\t1615554922656,\\n\\t\\t\\"Role\\":\\t20,\\n\\t\\t\\"Reason\\":\\t1\\n\\t}\\n}"

签名校验示例

Java
Python
PHP
Golang
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
//# 功能:第三方回调sign校验
//# 参数:
//#   key:控制台配置的密钥key
//#   body:腾讯云回调返回的body体
//#   sign:腾讯云回调返回的签名值sign
//# 返回值:
//#   Status:OK 表示校验通过,FAIL 表示校验失败,具体原因参考Info
//#   Info:成功/失败信息

public class checkSign {
    public static String getResultSign(String key, String body) throws Exception {
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        hmacSha256.init(secret_key);
        return Base64.getEncoder().encodeToString(hmacSha256.doFinal(body.getBytes()));
    }
    public static void main(String[] args) throws Exception {
        String key = "123654";
        String body = "{\\n" + "\\t\\"EventGroupId\\":\\t2,\\n" + "\\t\\"EventType\\":\\t204,\\n" + "\\t\\"CallbackTs\\":\\t1664209748188,\\n" + "\\t\\"EventInfo\\":\\t{\\n" + "\\t\\t\\"RoomId\\":\\t8489,\\n" + "\\t\\t\\"EventTs\\":\\t1664209748,\\n" + "\\t\\t\\"EventMsTs\\":\\t1664209748180,\\n" + "\\t\\t\\"UserId\\":\\t\\"user_85034614\\",\\n" + "\\t\\t\\"Reason\\":\\t0\\n" + "\\t}\\n" + "}";
        String Sign = "kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA=";
        String resultSign = getResultSign(key, body);

        if (resultSign.equals(Sign)) {
            System.out.println("{'Status': 'OK', 'Info': '校验通过'}");
        } else {
            System.out.println("{'Status': 'FAIL', 'Info': '校验失败'}");
        }
    }
}
# -*- coding: utf8 -*-
import hmac
import base64
from hashlib import sha256

# 功能:第三方回调sign校验
# 参数:
#   key:控制台配置的密钥key
#   body:腾讯云回调返回的body体
#   sign:腾讯云回调返回的签名值sign
# 返回值:
#   Status:OK 表示校验通过,FAIL 表示校验失败,具体原因参考Info
#   Info:成功/失败信息

def checkSign(key, body, sign):
    temp_dict = {}
    computSign = base64.b64encode(hmac.new(key.encode('utf-8'), body.encode('utf-8'), digestmod=sha256).digest()).decode('utf-8')
    print(computSign)
    if computSign == sign:
        temp_dict['Status'] = 'OK'
        temp_dict['Info'] = '校验通过'
        return temp_dict
    else:
        temp_dict['Status'] = 'FAIL'
        temp_dict['Info'] = '校验失败'
        return temp_dict

if __name__ == '__main__':
    key = '123654'
    body = "{\\n" + "\\t\\"EventGroupId\\":\\t2,\\n" + "\\t\\"EventType\\":\\t204,\\n" + "\\t\\"CallbackTs\\":\\t1664209748188,\\n" + "\\t\\"EventInfo\\":\\t{\\n" + "\\t\\t\\"RoomId\\":\\t8489,\\n" + "\\t\\t\\"EventTs\\":\\t1664209748,\\n" + "\\t\\t\\"EventMsTs\\":\\t1664209748180,\\n" + "\\t\\t\\"UserId\\":\\t\\"user_85034614\\",\\n" + "\\t\\t\\"Reason\\":\\t0\\n" + "\\t}\\n" + "}"
    sign = 'kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA='
    result = checkSign(key, body, sign)
    print(result)
<?php

class TlsEventSig {
private $key = false;
private $body = false;
public function __construct( $key, $body ) {
$this->key = $key;
$this->body = $body;
}

private function __hmacsha256() {
$hash = hash_hmac( 'sha256', $this->body, $this->key, true );
return base64_encode( $hash);
}
public function genEventSig() {
return $this->__hmacsha256();
}
}

$key="789";
$data="{\\n\\t\\"EventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t101,\\n\\t\\"CallbackTs\\":\\t1608086882372,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t20222,\\n\\t\\t\\"EventTs\\":\\t1608086882,\\n\\t\\t\\"UserId\\":\\t\\"222222_phone\\"\\n\\t}\\n}";

$api = new TlsEventSig($key, $data);
echo $api->genEventSig();
package main
import "fmt"
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
)

func main () {
var data = "{\\n\\t\\"EventGroupId\\":\\t1,\\n\\t\\"EventType\\":\\t101,\\n\\t\\"CallbackTs\\":\\t1608086882372,\\n\\t\\"EventInfo\\":\\t{\\n\\t\\t\\"RoomId\\":\\t20222,\\n\\t\\t\\"EventTs\\":\\t1608086882,\\n\\t\\t\\"UserId\\":\\t\\"222222_phone\\"\\n\\t}\\n}"
var key = "789"

//JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。
fmt.Println(hmacsha256(data,key))
}

func hmacsha256(data string, key string) string {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(data))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈