服务端集成
通过阅读本文,您可以快速搭建互动直播间的服务端(App Server)。
前提条件
操作步骤
在GitHub下载服务端源代码。
下载并解压源代码压缩包后,文件夹结构如下所示:
修改源代码配置
使用文本编辑器或VSCode等轻量级代码编辑器,打开
src/main/resources/application.yml
文件,修改配置。获取并设置AccessKey。关于如何获取AccessKey,请参见创建RAM用户。
paas: accessKey: LTAI*****aVjjv //阿里云账号或者子账号下的AccessKey accessKeySecret: 9NQ*****zF //阿里云账号或者子账号下的AccessKeySecret appId: * //在低代码音视频工厂的产品控制台的应用管理列表查看
设置AppServer相关字段。
此处设置为接口调用服务验签部分。关于验签的详情,请参见附录:服务验签。
impServer: appId: imp-room //可自己定义,AppServer应用ID,用于鉴权,推荐填写imp-room appServerUrl: * // 假如将本工程部署在服务器IP地址为11.22.33.44的机器上, // 应设置为http://11.22.33.44:8080,保证8080端口打开 appSignSecret: * //客户自己设置调用鉴权码,该鉴权码和客户端的SIGN_SECRET设置需保持一致
部署源代码
操作步骤
在源代码根目录的文件夹中执行以下Shell命令。
说明如果没有安装maven,需要先执行apt install maven安装maven。
mvn package
打包结束之后,在本级目录下会生成target文件夹。进入文件夹,可以看到
room-0.0.1-SNAPSHOT.jar
文件。打包时长受服务器带宽和性能影响。本例中第一次打包时间大约为3分钟。
在target目录执行以下命令。
cd target nohup java -jar room-0.0.1-SNAPSHOT.jar &
命令执行时看到nohup提示,输入回车使程序进入后台运行。
执行完成后,在当前目录下生成日志文件nohup.out,可通过cat nohup.out命令查看日志。若包含start success的字样,表示服务已启动成功。
注意事项
如果您购买的ECS内存较小,并且需要对服务端源码重新打包并部署,请执行以下操作,否则可能会因为内存不足导致打包失败。操作步骤如下所示:
执行jps命令查看当前正在运行的jar程序进程号。
执行
kill -9 jar程序进程号
关闭该进程。重新打包并部署。
附录:服务验签
签名机制:服务在发起调用请求时,会根据应用配置的鉴权码+公共参数+自定义参数进行签名,签名结果串与参与签名的公共参数一起包含在Headers中发起请求,消息接收方可依此进行验签。
签名公共参数如下所示:
参数 | 类型 | 是否必选 | 描述 |
---|---|---|---|
App-Id | String | 是 | 签名App标识,取值:推荐imp-room。 |
Signature | String | 是 | 签名结果串。 |
Signature-Method | String | 是 | 签名方式,取值:HMAC-SHA1。 更多信息,请参见HMAC-SHA1验签逻辑。 |
Timestamp | String | 是 | 请求的时间戳。日期格式按照ISO8601标准表示,使用UTC时间,格式为yyyy-MM-ddTHH:mm:ssZ。例如:2019-12-29T12:00:00Z为北京时间2019年12月29日的20点0分0秒。 |
Signature-Version | String | 是 | 签名算法版本,取值:1.0。 |
Signature-Nonce | String | 是 | 唯一随机数。在不同请求间使用不同的随机数值,防止网络重放攻击。 |
HMAC-SHA1验签逻辑
以Java语言为例,HMAC-SHA1验签逻辑如下所示:
private static final String ALGORITHM_NAME = "HmacSHA1";
private static final String ENCODING = "UTF-8";
/**
* @param signSecret 回调鉴权码
* @param method 请求方式,取值POST
* @param path 回调服务URL
* @param params 请求参数,KV形式
* @param headers 请求头部(含签名结果串和签名公共参数),header名全小写
*/
public static boolean verifySign(String signSecret, String method, String path,
Map<String, String> params,
Map<String, String> headers){
// 1. 获取签名结果串
String signature = headers.remove(SIGNATURE);
// 2. 请求params、headers、结果串等入参数检查,非空检查及签名方式、算法版本检查
// ...
// 3.构造签名字符串stringToSign
// 3.1 从headers中提取签名公共参数signedHeaders
// 3.2 构造规范化的params/signedHeaders字符串(参数按key排序后,组合成&key=value形式)
// 3.3 与method, path一起构造签名字符串stringToSign
// 4. 计算签名
String expectedSignature = sign(stringToSign, signSecret + "&");
// 5. 校验签名
return signature.equals(expectedSignature);
}
/**
* HMAC-SHA1签名计算
*/
public static String sign(String stringToSign, String signSecret) {
try {
Mac mac = Mac.getInstance(ALGORITHM_NAME);
mac.init(new SecretKeySpec(
signSecret.getBytes(ENCODING),
ALGORITHM_NAME
));
byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
String signBase64 = DatatypeConverter.printBase64Binary(signData);
return percentEncode(signBase64);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
throw new IllegalArgumentException(e.toString(), e);
}
}