grpc-js三方库移植(二)——移植策略
grpc-js三方库移植(二)——移植策略 简介 新建ets项目,创建library库,并将grpc-js主要功能代码拷贝至library目录下,进行原生node.js的ts代码进行arkTs环境下的node适配,解决编译问题,在应用demo中调用library导出的方法,进行功能调试。 具体步骤 一、项目构建 版本依赖 IDE版本 DevEco Studio 5.0.1 Release 下载路径
grpc-js三方库移植(二)——移植策略
简介
新建ets项目,创建library库,并将grpc-js主要功能代码拷贝至library目录下,进行原生node.js的ts代码进行arkTs环境下的node适配,解决编译问题,在应用demo中调用library导出的方法,进行功能调试。
具体步骤
一、项目构建
版本依赖
IDE版本 DevEco Studio 5.0.1 Release
下载路径:
https://developer.huawei.com/consumer/cn/download/
新建项目
新建应用,在应用中进行移植适配和功能调试
新建library
新建Static Library
配置文件
在entry模块中引入依赖 library库
代码移植
grpc-js源代码路径
ohos应用中grpc-js代码存放路径(将上图中的src目录下所有文件拷贝至library模块新建的ts目录下)
二、基本使用
library库方法导出
library/Index.ets文件
import * as grpc from './src/main/ts'
export { grpc }
entry中ets后缀文件调用library库方法
import { grpc } from 'library'
entry中ts后缀文件调用library库方法
前置条件:将library/Index.ets 文件改为 library/Index.ts文件
grpc导入方法也与ets文件调用有所不同:
import { grpc } from "library/Index";
三、编译适配
由于grpc-js在node环境依赖的很多模块以及语法的检查上,和arkTs并不都一致,所以grpc-js内的ts代码放到library库下使用时,会出现一些语法以及代码功能上的错误,需要进行适配,总的思路就是,用arkTs的模块来代替node原生但在arkTs不支持的模块,首先是确保编译可以通过,然后再进行功能的调试。
功能模块查找替换
示例1(arkTs中存在同功能模块):
原代码:
export interface CaCertificateUpdate {
caCertificate: Buffer;
}
Buffer是node.js的原生类型,arkTs不存在Buffer类型,使用@ohos.buffer模块的buffer.Buffer类型替换
import buffer from '@ohos.buffer';
export type Buffer = buffer.Buffer;
示例2(arkTs中不存在同功能模块,需要编写wrapper):
原代码
import { promises as dns } from 'dns';
private alternativeResolver = new dns.Resolver();
this.alternativeResolver.setServers([target.authority]);
this.alternativeResolver.resolve4(hostname),
this.alternativeResolver.resolve6(hostname),
this.alternativeResolver.resolveTxt(hostname);
const addressList = await dns.lookup(hostname, { all: true });
return dns.resolveTxt(hostname);
arkTs中不存在dns模块,无法使用类似的导入,这时候需要编写一个wrapper,实现一个dns的类,使其具备node.js中dns模块在grpc-js里面有用到的功能
编写dns wrapper:
// 创建WrapperResolver类,用于创建dns对象实例,constructor中打印log,后续代码调试时可查看调用信息
export class WrapperResolver {
private DOMAIN = 0x8691
private TAG = 'WrapperResolver'
private serverList: string[];
constructor() {
hilog.info(this.DOMAIN, this.TAG, 'create Resolver');
}
public getServers(): string[] {
return [
'8.8.8.8',
'2001:4860:4860::8888',
'8.8.8.8:1053',
'[2001:4860:4860::8888]:1053',
]
}
public setServers(paramList: string[]) {
this.serverList = paramList;
}
public resolve(){
}
public resolve4(param: string){
return param;
}
public resolve6(param: string){
return param;
}
public resolveAny(){}
public resolveCaa(){}
public resolveCname(){}
public resolveMx(){}
public resolveNaptr(){}
public resolveNs(){}
public resolvePtr(){}
public resolveSoa(){}
public resolveSrv(){}
public resolveTxt(param: string): Promise<string[][]>{
return [][param];
}
public reverse(){}
}
// dns实例
export class dns {
static lookup(hostname: string, arg1: { all: boolean }) {
let result:Promise<LookupAddress[]>;
return result
}
static Resolver() {
return new WrapperResolver();
}
static resolveTxt(hostname: string): Promise<string[][]> {
return [][hostname];
}
}
替换dns wrapper原代码调用:
import { dns, WrapperResolver } from './wrapper/dns';
private alternativeResolver: WrapperResolver;
this.alternativeResolver = new WrapperResolver();
this.alternativeResolver.setServers([target.authority]);
this.alternativeResolver.resolve4(hostname),
this.alternativeResolver.resolve6(hostname),
this.alternativeResolver.resolveTxt(hostname);
const addressList = await dns.lookup(hostname, { all: true });
return dns.resolveTxt(hostname);
可以看出来,除了类是单独构建并替换了原有的导入,代码中的改动是非常小的,只在创建实例的地方因为调用方法不同有些许改动,这样编写wrapper,代码后续维护也非常方便,只需要改动wrapper即可。
由于植入的wrapper定义的部分接口并没有具体的实现,所以接口调用时必须打印一些有辨识度的log,否则调试功能,程序运行时可能不知道执行到哪一步了。
更多推荐
所有评论(0)