初始化框架

在使用 RPC 之前,需先初始化 mPaaS 框架:

export default class EntryAbilityStage extends AbilityStage {
 async onCreate() {
 const app = this.context;
 MPFramework.create(app);
 
 const instance: MPFramework = MPFramework.instance;
 const ctx: Context = instance.context
 }
}


生成 RPC 代码

以下代码由控制台自动生成,若尚未升级控制台,可以手动按以下格式输入模型,如:VipInfo.ts

interface VipInfo{
 expireTime:number,
 level:number
}

模型中可以包含模型,如:userInfo.ts

interface UserInfo{
 vip:VipInfo,
 name:string,
 age:number
}

包装参数由控制台自动生成,如:LoginPostReq.ts

interface LoginPostReq{
  _mPaaSCustomBody:UserInfo
}

自动生成接口,如尚未升级控制台,可以先手动配置。以 Client.ets 为例。

import {MPRpc} from '@mpaas/rpc'

class Client{//<>中为返回值类型,needsign,ispb为必传字段
 async loginPost(req:LoginPostReq):Promise<string>{//返回类型为string
 return MPRpc.executeRpc<string>(this,{
 operationType:"com.antcloud.request.post",
 needSign:false,
 isPb:false
 },req);
 }
}

调用 RPC 接口

RPC 请求必须在子线程调用,可使用中间层中 MPRpcInterface 封装的子线程调用接口,回调方法默认为主线程。示例代码如下:

//前提条件初始化rpc
MPRpc.init();
function testRpc(){
  let cl = new Client();
  let account:VipInfo = {
    expireTime:1,
    level:1
  };
  let user:UserInfo = {
    vip:account,
    name:"handsome",
    age:14
  }
  let req:LoginPostReq ={
    _mPaaSCustomBody:user
  }
  cl.loginPost(req).then((result)=>{
    console.log("result")
  }).catch((e:Error)=>{
    console.log(e.message)//通过e.message可以拿到具体的报错原因
  });
}
说明

要使用 try catch 捕获异常,当网关异常时就会抛出,您可以根据 网关结果码说明 查询原因。

请求自定义配置

设置超时时间

添加 timeout 配置,代码如下:

import {MPRpc} from '@mpaas/rpc'

class Client{//<>中为返回值类型,needsign,ispb为必传字段
 async loginPost(req:UserInfo):Promise<string>{
 return MPRpc.executeRpc<string>(this,{
 operationType:"com.antcloud.request.post",
 needSign:false,
 isPb:false,
 timeout:1000000//设置超时时间,默认为1分钟
 },req);
 }
}

设置请求 URL

添加 URL 配置,代码如下:

import {MPRpc} from '@mpaas/rpc'

class Client{//<>中为返回值类型,needsign,ispb为必传字段
 async loginPost(req:UserInfo):Promise<string>{
 return MPRpc.executeRpc<string>(this,{
 operationType:"com.antcloud.request.post",
 needSign:false,
 isPb:false,
 url:"https://xxxx.xx/xx/"//设置请求 URL。默认为网关地址
 },req);
 }
}

设置请求 Header

添加 Header 配置,代码如下:

import {MPRpc} from '@mpaas/rpc'

//初始化header
let headers:Map<string,string> = new Map();
headers.set("key1","value1");
headers.set("key2","value2");

class Client{//<>中为返回值类型,needsign,ispb为必传字段
 async loginPost(req:UserInfo):Promise<string>{
 return MPRpc.executeRpc<string>(this,{
 operationType:"com.antcloud.request.post",
 needSign:false,
 isPb:false,
 header:headers //设置headers
 },req);
 }
}

自定义 RPC 拦截器

  1. 初始化拦截器。

    • preHandle 在请求前执行,参数返回 RpcInvokeContext 对象,可以进行 Header,URL,timeout 等操作,return false 表示进行拦截,rpc 接口可以 catch 异常,请求将终止。

    • postHandle 在请求后执行,参数返回 RpcInvokeContext 对象,可以获取 response header 等操作,return false 表示进行拦截,rpc 接口可以 catch 异常,请求将终止。

    • handleException,表示遇到异常时进行拦截。

    import {RpcInterceptor,RpcInvokeContext} from "@mpaas/rpc";
    
    class interceptor implements RpcInterceptor{
     preHandle(rpcInvokeContext: RpcInvokeContext): boolean {
     return true;
     }
     postHandle(rpcInvokeContext: RpcInvokeContext): boolean {
     return true;
     }
     handleException(rpcInvokeContext: RpcInvokeContext, exception: RPCException)
     {
     throw exception;
     }
    }
    
    
  2. 配置拦截器。

    • 拦截指定 RPC。

      在自动生成的代码中添加 interceptor 配置:

      import {MPRpc} from '@mpaas/rpc'
      import {RpcInterceptor,RpcInvokeContext} from "@mpaas/rpc";
      
      class interceptor implements RpcInterceptor{
       preHandle(rpcInvokeContext: RpcInvokeContext): boolean {
       return true;
       }
       postHandle(rpcInvokeContext: RpcInvokeContext): boolean {
       return true;
       }
       handleException(rpcInvokeContext: RpcInvokeContext, exception: RPCException)
       {
       throw exception;
       }
      }
      
      class Client{//<>中为返回值类型,needsign,ispb为必传字段
       async loginPost(req:UserInfo):Promise<string>{
       return MPRpc.executeRpc<string>(this,{
       operationType:"com.antcloud.request.post",
       needSign:false,
       isPb:false,
       interceptor:new interceptor()
       },req);
       }
      }
    • 设置全局拦截。

      MPRpc 接口中设置:

      import {RpcInterceptor,RpcInvokeContext} from "@mpaas/rpc";
      import {MPRpc} from '@mpaas/rpc'
      
      class interceptor implements RpcInterceptor{
       preHandle(rpcInvokeContext: RpcInvokeContext): boolean {
       return true;
       }
       postHandle(rpcInvokeContext: RpcInvokeContext): boolean {
       return true;
       }
       handleException(rpcInvokeContext: RpcInvokeContext, exception: RPCException)
       {
       throw exception;
       }
      }
       
      MPRpc.addGlobalInterceptor(new interceptor());
      
      

数据加密

rawfile 目录下添加 mpaasnetconfig.json 文件。其中:

  • type:加密类型,支持 ECC/RSA/SM2。

  • crypt: 是否开启加密。

  • gw:使用蚂蚁自研 gzip,必须设置为 true

  • pubKey:公钥,需与加密类型匹配。

  • gwList:支持加密的 URL,多个 URL 可以用,分割,只有命中 URL 的才会参与加密。

{
 "type": "ECC",//支持ECC/RSA/SM2
 "crypt": false,//是否开启加密
 "gw": true,//使用蚂蚁自研 gzip
 "pubKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEx796auKwF42leWWX/cwvffrvz/M2\nd6f4ovv4G7wmu45Ed+5WBDfp7vKHB0P3il4SXmvK6be6m1MhL2kkY8Kj0Q==\n-----END PUBLIC KEY-----",
 "gwList":"https://mgw.mpaas.cn-hangzhou.aliyuncs.com/mgw.htm,http://11.164.247.80/mgw.htm"
}

数据签名(临时方案)

在接口文件中进行配置,needSign 设置为 truesec 中设置 appsecretsignType 中设置签名类型,目前支持:MD5(type 为 0),SHA256(type 为 4), SHA1(type 为 1)。

import {MPRpc} from '@mpaas/rpc'

class Client{//<>中为返回值类型,needsign,ispb为必传字段
 async loginPost(req:UserInfo):Promise<string>{
 return MPRpc.executeRpc<string>(this,{
 operationType:"com.antcloud.request.post",
 needSign:true,(默认为false)
 isPb:false,
 sec:"sss",
 signType:0 //如果不填,默认值为0 md5 (默认不填为md5)
 },req);
 }
}

数据签名(安全图片)

在接口文件中进行配置,needSign 设置为 truesignType 中设置签名类型,目前支持:MD5(type 为 0),SHA256(type 为 4), SM3(type 为 5)。

生成安全图片

当前版本尚未提供自动化工具,需客户提供相关信息,由 mPaaS 方帮助生成。需要提供的信息包括 appIdworkspaceId应用包名appsecret 应用签名 fingerPrint。

其中 fingerPrint 可以通过鸿蒙官方接口获取,建议接入方使用统一签名,否则针对不同签名需要生成不同的图片。

获取 fingerPrint 的接口如下:

import bundleManager from '@ohos.bundle.bundleManager';

let info = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
let finger = info.signatureInfo.fingerprint;

获得安全图片后,将其放在 rawfile 目录下即可。

针对全局

  • 可以设置全局 secret

    MPFramework.instance.appSecret = "xxxxxx"
  • 可以利用全局拦截器进行设置。

    import {RpcInterceptor,RpcInvokeContext} from "@mpaas/rpc";
    import {MPRpc} from '@mpaas/rpc'
    
    class interceptor implements RpcInterceptor{
     preHandle(rpcInvokeContext: RpcInvokeContext): boolean {
     rpcInvokeContext.setNeedSign(true);
     rpcInvokeContext.setSignType(0);
     rpcInvokeContext.setSecret("xxxx");
     return true;
     }
     postHandle(rpcInvokeContext: RpcInvokeContext): boolean {
     return true;
     }
     handleException(rpcInvokeContext: RpcInvokeContext, exception: RPCException)
     {
     throw exception;
     }
    }
     
    MPRpc.addGlobalInterceptor(new interceptor());