DEV Community

Cover image for HarmonyOS development: Far Field communication service rcp interceptor problem
程序员一鸣
程序员一鸣

Posted on

HarmonyOS development: Far Field communication service rcp interceptor problem

Foreword

this paper is based on api13.

In the previous article, we briefly summarized the session problem in rcp. In this article, we will talk about the interceptor problem in rcp. According to normal development, there is no problem in the interceptor. After all, it is a very official development method, but after combining the creation of a session, this problem will be exposed.

Declare an interceptor and print the header parameters passed in by the request:

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)
  }
}
Enter fullscreen mode Exit fullscreen mode

let's use the case in the previous article to simply receive a header parameter.

private doHttp(headers?: rcp.RequestHeaders) {

    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)
    }

    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)
    })

  }
Enter fullscreen mode Exit fullscreen mode

Let's make two requests and test them:

the first request

this.doHttp({
            "content-type": "application/json"
          })
Enter fullscreen mode Exit fullscreen mode

second request

this.doHttp({
            "content-type": "text/plain"
          })
Enter fullscreen mode Exit fullscreen mode

look at the print in the interceptor

Image description

the problem is already obvious, clearly the request header parameters have been modified, why is it printed or passed in the first request?

Cause of the problem

in fact, presumably, everyone saw the problem at a glance. In the previous article, We optimized the rcp session and adopted the rcp multiplexing mechanism. Although the rcp session problem was solved, because the headers parameters were imported into the rcp session, multiplexing meant that all session configurations were reused, which led to the problem that some parameters, such as headers, could not be updated.

Of course, you can use non-reuse sessions and close them directly after each session, but this frequent creation and closure will consume resources. Of course, if you don't care, you can do the same.

Problem solving

The solution is also very simple. Some flexible and variable parameters are handled by the Request object, such as headers and cookies.

 let req = new rcp.Request('xxx', 'GET', headers)
Enter fullscreen mode Exit fullscreen mode

Or the above request method, let's look at the printing in interception:

Image description

however, it was found that the parameters in the interception had changed.

Other issues

many people will do a lot of operations in the interceptor, such as unified error handling, log printing, data redirection, etc. Especially when data is redirected, value must be assigned according to its own return type. This is very important. For example, json is received over there, and json must be received when data is assigned, especially when the network library is encapsulated.

If you only want to change a json, for example, it is encrypted before acquisition and returned again after decryption, then use toString instead of toJSON.

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':'abnerming'}",
      toJSON: () => null
    }
    return Promise.resolve(response)
  }
}
Enter fullscreen mode Exit fullscreen mode

Looking at the log print:

Image description

related Summary

regarding the interceptor of rcp, the most important thing is that when the session is reused, if there are required parameters in the Request object, use the Request directly instead of the session.

Top comments (0)