写点什么

HarmonyOS 5.0 应用开发——RCP 框架的使用

作者:高心星
  • 2024-10-31
    江苏
  • 本文字数:4155 字

    阅读完需:约 14 分钟

HarmonyOS 5.0应用开发——RCP框架的使用

【高心星出品】

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移动应用开发等课程的教学工作。参与开发《鸿蒙应用开发基础》和《鸿蒙项目实战》等课程。

评论

发布
暂无评论
HarmonyOS 5.0应用开发——RCP框架的使用_鸿蒙_高心星_InfoQ写作社区