鸿蒙开发:远场通信服务rcp拦截器问题

前言

本文基于Api13。

上篇文章,简单的对rcp中的会话问题做了概述,本篇文章,我们聊一聊rcp中的拦截器问题,按照正常开发,其实拦截器中也不存在问题的,毕竟都是很官方的开发方式,但是在结合了创建会话之后,这个问题就会暴露出来。

声明一个拦截器,打印一下请求传入的头参:

TypeScript 复制代码
class MyInterceptor implements rcp.Interceptor {
  intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    console.log("===拦截器打印headers:" + JSON.stringify(context.request.headers))
    return next.handle(context)
  }
}

我们还是用上一篇文章中的案例,简单接收一个headers参数。

TypeScript 复制代码
private doHttp(headers?: rcp.RequestHeaders) {
    // 定义sessionConfig对象
    const sessionConfig: rcp.SessionConfiguration = {
      headers: headers,
      interceptors: [new MyInterceptor()], //拦截器
      requestConfiguration: {
        transfer: {
          autoRedirect: true,
          timeout: {
            connectMs: 10000,
            transferMs: 10000
          },
        },
        tracing: {
          verbose: true
        }
      }
    }
    // 创建通信会话对象
    if (this.mSession == undefined) {
      this.mSession = rcp.createSession(sessionConfig)
    }
    // 定义请求对象rep
    let req = new rcp.Request('xxx', 'GET')
    // 发起请求
    this.mSession.fetch(req).then((response) => {
      console.log("=======SUCCESS:" + response.toString())
    }).catch((err: BusinessError) => {
      console.log("=======ERROR:" + err.message)
    })

  }

我们发起两次请求,测试一下:

第一次请求

TypeScript 复制代码
this.doHttp({
            "content-type": "application/json"
          })

第二次请求

TypeScript 复制代码
this.doHttp({
            "content-type": "text/plain"
          })

看下拦截器中的打印

问题已经很明显了,明明请求头参数做了修改,为什么打印的还是第一次请求中传递的?

问题原因

其实想必,大家一眼就看到了问题,我们在上篇文章中,针对rcp会话做了优化,采取了rcp复用机制,虽然解决了rcp的会话问题,但是由于headers参数是在rcp会话中的传入的,复用,意味着所有的会话配置都进行了复用,这就导致了,一些参数,比如headers就无法更新的问题。

当然了,你可以采用不复用会话,每次会话后直接关闭,但是这种频繁的创建关闭会很消耗资源,当然了,如果你不在乎,也可以这么去做。

问题解决

解决方式也是非常的简单,一些灵活可变的参数,交由Request对象处理,比如headers,cookies等。

TypeScript 复制代码
 let req = new rcp.Request('xxx', 'GET', headers)

还是上边的请求方式,我们再来看下拦截中的打印:

可是发现,拦截中的参数已经发生了变化。

其它问题

很多人都会在拦截器中做很多的操作,比如统一错误处理,日志打印,数据重定向等等,特别是在数据重定向的时候,一定要根据自身的返回类型进行进行赋值,这个是非常重要的,比如那边接收的是json,在数据赋值的时候一定是json,特别是在网络库封装的时候。

如果你只想改变一个json,比如获取前是加密的,解密后再次返回,那么就通过toString,而不是toJSON。

TypeScript 复制代码
class MyInterceptor implements rcp.Interceptor {
  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    let res = await next.handle(context)
    let response: rcp.Response = {
      request: res.request,
      statusCode: res.statusCode,
      headers: res.headers,
      toString: () => "{'name':'程序员一鸣'}",
      toJSON: () => null
    }
    return Promise.resolve(response)
  }
}

在看日志打印:

相关总结

关于rcp的拦截器问题,最重要的就是会话复用的时候,如果Request对象中有需要的参数,就直接用Request中的,而不是使用session中的。

相关推荐
消失的旧时光-19438 分钟前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon1 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon1 小时前
VSYNC 信号完整流程2
android
dalancon1 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
不爱吃糖的程序媛2 小时前
OpenHarmony 工程结构剖析
harmonyos
白玉cfc2 小时前
接口与API设计
ios·objective-c
用户69371750013842 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android3 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才3 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶4 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle