文档版本:20220113-100
变更历史:
API版本 | 发版日期 | 更新内容 |
---|---|---|
V1.0 | 2022/1/13 | 首次发版 |
1 PCU信息简介
Peak concurrent users简称PCU,表示峰值并发用户数。
2 签名算法
2.1 签名算法说明
海马云API会对每个请求进行身份验证,用户需要使用安全凭证,经过特定的步骤对请求进行签名(Signature),每个请求都需要在公共参数中指定该签名结果并以指定的方式和格式发送请求。签名通过以下方式帮助保护请求:
- 验证请求者的身份。
签名确保请求是由持有有效访问密钥的人发送的。请联系项目对接人员获取密钥相关信息。 - 保护传输中的数据。
为了防止请求在传输过程中被篡改,海马云API会使用请求参数来计算请求的base64编码,并将生成的base64编码加密后作为请求的一部分,发送到海马云API服务器。服务器会使用收到的请求参数以同样的过程计算base64编码,并验证请求中的base64编码。如果请求被篡改,将导致base64编码不一致,海马云API将拒绝本次请求。
2.2 签名生成步骤
1) 接入方使用此格式拼接:key:%s,rand:%s,timestamp:%d,expiryInterval:%d,tokenRaw。
2) 接入方将tokenRaw使用md5生成32位摘要信息,token。
3) 接入方将payload描述的内容经过encode编码,传入encoded字段。
4) 接入方按照此格式拼接数据:accessKeyId:%s,encoded:%s,token:%s,记作signRaw。
5) 接入方将signRaw使用md5生成32位摘要信息,记作sign。
6) 海马云在验签通过后,会将encode数据经过base64解码后还原到payload字段中。
⚠注意:
接入方不通过payload传数据,payload由海马云经过base64解码后还原。
表2-1 签名算法参数说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
key | String | 是 | 提供给接入方的apiToken |
rand | String | 是 | 接入方随机生成的字符串,32位 |
timestamp | Long | 是 | 请求时间戳,当时间戳与服务端时间戳偏移大时会导致校验失败,单位为ms |
expiryInterval | Long | 是 | token有效期,单位为s, 建议定义为180s以上,避免服务器时间差导致验签失败 |
2.3 签名示例
为了更清楚地解释签名过程,下面以实际python编程为例,将上述的签名过程具体实现。代码只为解释签名过程,并不具备通用性。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import base64
import hashlib
import json
import time
t = time.time()
timestamp = (int(round(t * 1000))) # 毫秒级时间
def generate_sign(accessKeyId, apiToken, payload, expiry_interval=1000000):
m = hashlib.md5()
# 步骤1
original_token_str = 'key:%s,rand:%s,timestamp:%d,expiryInterval:%d' % (apiToken, '1', timestamp, expiry_interval)
# 步骤2
m.update(original_token_str.encode('utf-8'))
str_md5 = m.hexdigest()
# 步骤3
str_payload = json.dumps(payload, separators=(',', ":"))
base64_payload = base64.encodebytes(str_payload.rstrip('\n').encode())
decode = base64_payload.decode('utf-8')
# 步骤4
original_sign_str = 'accessKeyId:%s,encoded:%s,token:%s' % (accessKeyId, decode, str_md5)
# 步骤5
n = hashlib.md5()
n.update(original_sign_str.encode('utf-8'))
return n.hexdigest()
3 PCU状态信息查询接口
3.1 请求信息
接入方调用本接口,获取海马云游戏服务相关PCU信息。显示接入方总量的实例限额、总使用量及游戏包/游戏渠道的使用情况。
表3-1 请求信息说明
请求信息内容 | 说明 |
---|---|
URL | https://sdi-rel.haimawan.com/pcu/rt/v3 |
Method | POST |
Content-Type | application/json |
Accept | application/json |
请求参数(payload)示例:
{
·"conditions": {
"pkgName": "com.tencent.tmgp.sgame",
"appChannel": "test"
}
}
表3-2 请求参数说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
accessKeyId | String | 是 | 由海马云提供的接入唯一标识 |
encoded | String | 是 | payload参数base64编码后的字符串 |
expiryInterval | Long | 是 | token有效期,单位为s |
rand | String | 是 | 接入方随机生成的字符串 |
sign | String | 是 | 请参见签名算法 |
timestamp | Long | 是 | 请求时间戳,当时间戳与服务端时间戳偏移大时会导致校验失败,单位为ms |
payload | Object | 否 | 见PcuInfoRequest结构说明,接入方无需上传该字段,海马云==会由encoded字段base64解码后获得具体数据 |
表3-3 PcuInfoRequest结构说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
conditions | Map<String,Object> | 否 | 查询条件,见conditions结构说明 |
表3-4 conditions结构说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
pkgName | String | 否 | 需要查询的包名,示例:com.tencent.tmgp.sgame |
appChannel | String | 否 | 需要查询的渠道名称,示例:1001 |
3.2 响应报文
响应代码示例如下所示。
无查询条件:
{ "code": 0, "details": { "date": "2020-11-05 10:54:42", "hsnTotal": 77, "inServiceNum": 10 } }
查询appChannel:
{ "code": 0, "details": { "channelDetails": [ { "appChannel": "100_ad_1", "gameDetails": [ { "inServiceNum": 2, "name1": "贪吃蛇大作战®", "pkgName": "com.wepie.snake.game_demo" }, { "inServiceNum": 3, "name": "开心消消乐®", "pkgName": "com.happyelements.AndroidAnimal" } ] } ], "date": "2020-11-05 10:54:42", "hsnTotal": 77, "inServiceNum": 10 } }
查询pkgName:
{ "code": 0, "details": { "channelDetails": [ { "appChannel": "100_ad_1", "gameDetails": [ { "inServiceNum": 2, "name": "贪吃蛇大作战®", "pkgName": "com.wepie.snake.game_demo" } ] }, { "appChannel": "100_ad_2", "gameDetails": [ { "inServiceNum": 2, "name": "贪吃蛇大作战®", "pkgName": "com.wepie.snake.game_demo" } ] } ], "date": "2020-11-05 10:54:42", "hsnTotal": 77, "inServiceNum": 10 } }
查询pkgName+appChannel:
{ "code": 0, "details": { "channelDetails": [ { "appChannel": "100_ad_1", "gameDetails": [ { "inServiceNum": 2, "name": "贪吃蛇大作战®", "pkgName": "com.wepie.snake.game_demo" } ] } ], "date": "2020-11-05 10:54:42", "hsnTotal": 77, "inServiceNum": 10 } }
表3-5 响应报文参数说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
code | Integer | 是 | 请求处理结果。 0:表示请求成功 1:表示请求失败 |
errorCode | String | 否 | 错误码,详情请参见错误码 |
errorMsg | String | 否 | 错误码对应的错误描述信息 |
details | Object | 否 | 返回报文详情,当请求失败时为空 |
表3-6 details结构说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
date | String | 是 | 数据生成时间,精确到秒,示例:2020-03-10 18:36:30 |
hsnTotal | Integer | 是 | 日使用限额总数,示例:200 |
inServiceNum | Integer | 是 | 当前accessKeyId下服务状态实例总数 , 具体描述:当前accessKeyId下,正在进行游玩的用户总数,示例:100 |
channelDetails | List<Object> | 否 | 渠道维度详情数据列表,详情请参见channelDetails结构说明 |
表3-7 channelDetails结构说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
appChannel | String | 是 | 渠道名称,示例:1001 |
gameDetails | List<Object> | 是 | 各游戏维度详情数据列表 |
表3-8 gameDetails结构说明
参数 | 类型 | 必填项 | 说明 |
---|---|---|---|
name | String | 是 | 游戏名称(查询不到则显示包名),示例:王者荣耀 |
pkgName | String | 是 | 游戏包名,示例:com.tencent.tmgp.sgame |
inServiceNum | Integer | 是 | 当前游戏服务状态实例总数的具体描述,即当前accessKeyId、game维度下正在进行游玩的用户总数,示例:70 |
4 错误码
表4-1 错误码
错误码 | 说明 |
---|---|
401000000 | 请求出错 |
401000001 | 请求参数非法 |
401000002 | 日期参数非法 |
401000003 | 系统维护中,请稍后再试 |
401001001 | 请求参数签约验证失败 |
401001002 | 请求参数验证失败 |
401001003 | 请求参数不能为空 |
401001004 | 请求参数集合不能为空 |
401001005 | 请求参数最小值验证失败 |
401001006 | accessKeyId不存在 |
401001009 | 操作过于频繁,请稍后再试 |