实时音视频 旁路转推回调

服务端转推回调支持将你使用 旁路转推 REST API 产生转推 CDN 的事件,以 HTTP/HTTPS 请求的形式通知到你的服务器。可以以向腾讯云提供相关的配置信息来开通该服务。

相关产品
实时音视频 产品页,含版本规格、价格与购买入口。

一、配置信息

实时音视频 TRTC 控制台支持自助配置回调信息,配置完成后即可接收事件回调通知。详细操作指引请参见 回调配置。

注意:你需要提前准备以下信息:

二、超时重试

事件回调服务器在发送消息通知后,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, "EventMsTs": "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 房间名(类型与客户端房间号类型一致)
RoomType Number 0表示数字房间号,1表示字符串房间号
EventMsTs String 事件发生的 Unix 时间戳,单位为毫秒
UserId String 发起任务时指定的伴生机器人的用户 ID(AgentParams.UserId)
TaskId String 任务 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}"

十三、签名校验示例

JavaPythonPHPGolangimport 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 hmacimport base64from 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_dictif __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)<?phpclass 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 mainimport "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))}

赞 (0)
上一篇 4天前
下一篇 4天前