首页 服务端集成

服务端集成

更新时间: 2022-02-25 14:35:46

通过阅读本文,您可以快速搭建互动直播间的服务端(App Server)。

前提条件

操作步骤

  1. GitHub下载服务端源代码。

    下载并解压源代码压缩包后,文件夹结构如下所示:服务端demo源代码

  2. 修改源代码配置

    使用文本编辑器或VSCode等轻量级代码编辑器,打开src/main/resources/application.yml文件,修改配置。

    修改源代码配置APPserver

  3. 获取并设置AccessKey。关于如何获取AccessKey,请参见创建RAM用户

    paas:
        accessKey: LTAI*****aVjjv //阿里云账号或者子账号下的AccessKey
        accessKeySecret: 9NQ*****zF //阿里云账号或者子账号下的AccessKeySecret
        appId: * //在低代码音视频工厂的产品控制台的应用管理列表查看
  4. 设置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设置需保持一致

部署源代码

操作步骤

  1. 在源代码根目录的文件夹中执行以下Shell命令。

    说明

    如果没有安装maven,需要先执行apt install maven安装maven。

    mvn package
  2. 打包结束之后,在本级目录下会生成target文件夹。进入文件夹,可以看到room-0.0.1-SNAPSHOT.jar文件。

    打包时长受服务器带宽和性能影响。本例中第一次打包时间大约为3分钟。

    room-0
  3. 在target目录执行以下命令。

    cd target
    nohup java -jar room-0.0.1-SNAPSHOT.jar &
  4. 命令执行时看到nohup提示,输入回车使程序进入后台运行。

  5. 执行完成后,在当前目录下生成日志文件nohup.out,可通过cat nohup.out命令查看日志。若包含start success的字样,表示服务已启动成功。

注意事项

如果您购买的ECS内存较小,并且需要对服务端源码重新打包并部署,请执行以下操作,否则可能会因为内存不足导致打包失败。操作步骤如下所示:

  1. 执行jps命令查看当前正在运行的jar程序进程号。

  2. 执行kill -9 jar程序进程号关闭该进程。

  3. 重新打包并部署。

附录:服务验签

签名机制:服务在发起调用请求时,会根据应用配置的鉴权码+公共参数+自定义参数进行签名,签名结果串与参与签名的公共参数一起包含在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);
    }
}