HarmonyOS 5.0 应用开发——RCP 框架的使用
- 2024-10-31 江苏
本文字数:4155 字
阅读完需:约 14 分钟
【高心星出品】
RCP 框架的使用
Remote Communication Kit 中的 @hms.collaboration.rcp(后续简称 RCP)指的是远程通信平台(remote communication platform),RCP 提供了网络数据请求功能,相较于 Network Kit 中 HTTP 请求能力,RCP 更具易用性,且拥有更多的功能。在开发过程中,如果有些场景使用 Network Kit 中 HTTP 请求能力达不到预期或无法实现,那么就可以尝试使用 RCP 中的数据请求功能来实现。
RCP vs HTTP
为了方便了解 RCP 与 HTTP 的区别,可以从功能分类、功能名称和功能描述这三个方面进行对比,主要区别如下:
请求对象和应答对象
请求对象 rcp.Request
let req = new rcp.Request(url: URLOrString, method?: HttpMethod, headers?: RequestHeaders, content?: RequestContent, cookies?: RequestCookies, transferRange?: TransferRange | TransferRange[], configuration?: Configuration)
应答对象 rcp.Response
let req = new rcp.Request(url: URLOrString, method?: HttpMethod, headers?: RequestHeaders, content?: RequestContent, cookies?: RequestCookies, transferRange?: TransferRange | TransferRange[], configuration?: Configuration)
简单的应用
该测试应用包含了基本发送 get、post 请求,编写请求和应答拦截器、下载文件、下载文件流、上传文件、上传文件流等功能的实现。通过编写该案例可以覆盖大部分 RCP 框架的应用场景。
Get 请求
创建会话对象
创建请求对象
发起请求
let sessionconfig: rcp.SessionConfiguration = {
//请求服务器基准地址
baseAddress: 'https://httpbin.org'
}
let session = rcp.createSession(sessionconfig) //创建会话
let req = new rcp.Request('/get?id=10&name=gxx', 'GET') //创建get请求
session.fetch(req).then((res: rcp.Response) => { //发送请求获取应答
this.message = JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close() //关闭会话
})
Post 请求
创建会话对象
创建请求对象
发起请求
let userinfo: UserType = {
//post请求携带数据
id: '10',
name: 'gxx'
}
let sessionconfig: rcp.SessionConfiguration = {
//会话配置项
baseAddress: 'https://httpbin.org'
}
let session = rcp.createSession(sessionconfig) //创建会话
let req = new rcp.Request('/post', 'POST', undefined, userinfo) //创建请求
session.fetch(req).then((res: rcp.Response) => { //发送请求获得应答
this.message = 'gxxt ' + JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close() //关闭会话
})
使用拦截器
自定义拦截器
拦截器需要实现 rcp.Interceptor 接口并重写 interceptor 方法。
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response>
context:包含了请求对象和会话对象,可以获取请求的信息。
next:请求执行器,可以执行 context 获取应答结果。
Promise<rcp.Response>:返回一个应答结果,可以是 next 执行的结果也可以是自己创建的应答结果。
下面案例定义一个拦截器,将请求中携带数据修改,并拦截应答结果,只返回部分应答结果。
export class HttpReqInterceptor implements rcp.Interceptor {
// 拦截方法
//context 包含所有的请求和会话信息
//next 下一个拦截器
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
let url = context.request.url
if (url.hostname === 'httpbin.org' && url.params.has('id') && context.request.method === 'GET') { //判定地址中半酣httpbin并且携带数据有id
let id = url.params.get('id')
url.params.set('id', 'id-' + id) //将id的值替换为id-
}
let res=await next.handle(context) //获取应答数据
let nres:rcp.Response={ //在应答数据的基础上创建了新的应答数据
request:res.request,
headers:res.headers,
statusCode:res.statusCode,
// 将返回的数据进行了截取只获取args的值
toJSON:()=> JSON.parse(res.toString()!.substring(res.toString()!.indexOf(':')+1,res.toString()!.indexOf('}')+1).replace('\n',''))
}
return nres //返回了新的应答数据
}
}
创建会话对象
创建请求对象
发起请求
let sessionconfig: rcp.SessionConfiguration = {
//请求服务器基准地址
baseAddress: 'https://httpbin.org',
interceptors: [//使用自定义的拦截器
new HttpReqInterceptor()
]
}
let session = rcp.createSession(sessionconfig) //创建会话
let req = new rcp.Request('/get?id=10&name=gxx', 'GET') //创建get请求
session.fetch(req).then((res: rcp.Response) => { //发送请求获取应答
this.message = 'gxxt ' + (res.toJSON() as UserType).name//将应答结果转化为自己定义的类型
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close() //关闭会话
})
下载文件
创建文件保存位置
// 文件保存位置
let downloadfile: rcp.DownloadToFile = {
kind: 'folder', //目录类型
path: getContext(this).filesDir //目录的路径
}
创建会话对象
下载文件
// 图片资源地址
let url =
'https://ts1.cn.mm.bing.net/th/id/R-C.57384e4c2dd256a755578f00845e60af?rik=uy9%2bvT4%2b7Rur%2fA&riu=http%3a%2f%2fimg06file.tooopen.com%2fimages%2f20171224%2ftooopen_sy_231021357463.jpg&ehk=whpCWn%2byPBvtGi1%2boY1sEBq%2frEUaP6w2N5bnBQsLWdo%3d&risl=&pid=ImgRaw&r=0'
// 会话对象
let session: rcp.Session = rcp.createSession()
// 文件保存位置
let downloadfile: rcp.DownloadToFile = {
kind: 'folder',
path: getContext(this).filesDir
}
// 开始下载文件
session.downloadToFile(url, downloadfile).then((res) => {
this.message = 'gxxt a' + JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close()
})
下载文件流
创建文件写流
let downloadto: rcp.DownloadToStream = {
kind: 'stream', //类型为流
stream: {
write: (buffer: ArrayBuffer) => { //每次下载的资源保存在buffer中,会执行多次
let len= fileIo.writeSync(f.fd, buffer) //写入到文件中
return Promise.resolve(len) //返回写入文件的字节个数
}
}
}
创建会话对象
读取网络资源的字节流
将该字节流保存在设备上
// 图片资源地址
let url =
'https://ts1.cn.mm.bing.net/th/id/R-C.57384e4c2dd256a755578f00845e60af?rik=uy9%2bvT4%2b7Rur%2fA&riu=http%3a%2f%2fimg06file.tooopen.com%2fimages%2f20171224%2ftooopen_sy_231021357463.jpg&ehk=whpCWn%2byPBvtGi1%2boY1sEBq%2frEUaP6w2N5bnBQsLWdo%3d&risl=&pid=ImgRaw&r=0'
let session: rcp.Session = rcp.createSession() //会话对象
let file = getContext(this).filesDir + '/test2.jpg' //文件保存路径
let f: fileIo.File = fileIo.openSync(file, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY) //文件对象
let downloadto: rcp.DownloadToStream = {
kind: 'stream',
stream: {
write: (buffer: ArrayBuffer) => { //每次下载的资源保存在buffer中,会执行多次
let len= fileIo.writeSync(f.fd, buffer) //写入到文件中
return Promise.resolve(len) //返回写入文件的字节个数
}
}
}
session.downloadToStream(url, downloadto).then((res: rcp.Response) => { //下载文件成字节流
this.message = 'gxxt downloadtostream ' + JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close()
})
上传文件
要上传的文件对象
// 文件地址
let uploadfromfile: rcp.UploadFromFile = {
fileOrPath: getContext(this).filesDir + '/test1.jpg'
}
创建会话对象
上传文件请求
// 上传地址
let url = 'https://httpbin.org/post'
// 会话对象
let session = rcp.createSession()
// 文件地址
let uploadfromfile: rcp.UploadFromFile = {
fileOrPath: getContext(this).filesDir + '/test1.jpg'
}
// 开始上传
session.uploadFromFile(url, uploadfromfile).then((res: rcp.Response) => {
this.message = 'gxxt ' + JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close()
})
上传文件流
要上传文件对象读流
let uploadstream: rcp.UploadFromStream = {
stream: {
read: (buffer: ArrayBuffer) => { //每次将文件的字节读入buffer 等待上传到服务器
let len = fileIo.readSync(file.fd, buffer)
console.log('gxxt 读了:', len)
return Promise.resolve(len)
}
}
}
创建会话对象
上传文件对象流
// 文件上传地址
let url = 'https://httpbin.org/post'
// 创建会话对象
let session = rcp.createSession()
// 需要上传的文件
let file: fileIo.File = fileIo.openSync(getContext(this).filesDir + '/test1.jpg', fileIo.OpenMode.READ_ONLY)
let uploadstream: rcp.UploadFromStream = {
stream: {
read: (buffer: ArrayBuffer) => { //每次将文件的字节读入buffer 等待上传到服务器
let len = fileIo.readSync(file.fd, buffer)
console.log('gxxt 读了:', len)
return Promise.resolve(len)
}
}
}
session.uploadFromStream(url, uploadstream).then((res: rcp.Response) => { //开始上传
this.message = 'gxxt ' + JSON.stringify(res)
}).catch((e: Error) => {
this.message = 'gxxt ' + e.message
}).finally(() => {
session.close()
})
高心星
天将降大任于斯人也,必先苦其心志。 2024-10-17 加入
华为开发者专家(HDE)。 10年教学经验,兼任多家科技公司技术顾问。先后从事JavaEE项目开发、Python爬虫、HarmonyOS移动应用开发等课程的教学工作。参与开发《鸿蒙应用开发基础》和《鸿蒙项目实战》等课程。
评论