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_RECOVERINGPUBLISH_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))
    }
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持