初始化框架
在使用 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 拦截器
初始化拦截器。
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; } }
配置拦截器。
拦截指定 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
设置为 true
,sec
中设置 appsecret
,signType
中设置签名类型,目前支持: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
设置为 true
,signType
中设置签名类型,目前支持:MD5(type 为 0),SHA256(type 为 4), SM3(type 为 5)。
生成安全图片
当前版本尚未提供自动化工具,需客户提供相关信息,由 mPaaS 方帮助生成。需要提供的信息包括 appId、workspaceId、应用包名、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());