HTTP网络数据上报

本文介绍如何使用SDK上报网络数据。

功能描述

SDK提供HTTP网络数据上报接口,用于业务应用上报自己的网络请求数据,在控制台查看网络请求的统计数据。

说明

当前鸿蒙平台没有全局的网络监听方法,所以需要通过上报接口,进行主动上报。

接口定义

定义如下:

/**
 * 网络数据上报
 */
export interface INetworkEventReporter {
  /**
   * 配置请求的url
   * @param url
   * @returns
   */
  url(url: string): INetworkEventReporter;

  /**
   * 配置请求的选项
   * @param options
   * @returns
   */
  httpOptions(options: http.HttpRequestOptions): INetworkEventReporter;

  /**
   * 配置请求的错误异常
   * @param error
   * @returns
   */
  error(error: Error): INetworkEventReporter;

  /**
   * 配置请求的响应
   * @param response
   * @returns
   */
  httpResponse(response: http.HttpResponse): INetworkEventReporter;

  /**
   * 配置业务错误码
   * @param code
   * @returns
   */
  businessCode(code: string): INetworkEventReporter;

  /**
   * 配置响应header
   * @param headers
   * @returns
   */
  responseHeader(headers: Object): INetworkEventReporter;

  /**
   * 配置响应的状态码
   * @param code
   * @returns
   */
  statusCode(code: number): INetworkEventReporter;

  /**
   * 配置rcp请求
   * @param request
   * @returns
   */
  rcpRequest(request: rcp.Request): INetworkEventReporter;

  /**
   * 配置rcp响应
   * @param response
   * @returns
   */
  rcpResponse(response: rcp.Response): INetworkEventReporter;

  /**
   * 触发上报
   */
  report(): void;
}

export interface IPerformanceApi extends IPlugin {
  /**
   * 获取一个网络上报接口
   * @returns 
   */
  networkEventReporter(): INetworkEventReporter;
}

鸿蒙平台提供两种HTTP请求API分别是HTTP数据请求Remote Communication Kit

网络上报接口针对不同的请求方法,提供了丰富的方法,具体说明如下

配置方法

场景说明

url(url: string)

HTTP数据请求场景使用,配置请求的url,必须配置

httpOptions(options: http.HttpRequestOptions)

HTTP数据请求场景使用,配置请求的参数,建议配置

error(error: Error)

HTTP数据请求场景使用,配置错误信息,失败时配置,建议配置

httpResponse(response: http.HttpResponse)

HTTP数据请求场景使用,配置响应,建议配置

businessCode(code: string)

场景通用,配置业务错误码,建议配置

responseHeader(headers: Object)

HTTP数据请求requestInStream 场景使用,配置响应header,建议配置

statusCode(code: number)

HTTP数据请求requestInStream 场景使用,配置HTTP响应码,建议配置

rcpRequest(request: rcp.Request)

Remote Communication Kit场景使用,配置请求,必须配置

rcpResponse(response: rcp.Response)

Remote Communication Kit场景使用,配置响应,必须配置

report()

结束配置,上报本次网络请求数据

代码示例

  • HTTP数据请求场景,使用request方法发起请求。

        let httpRequest = http.createHttp();
        const options: http.HttpRequestOptions = {
          method: http.RequestMethod.POST,
          // 省略其它参数配置
        }
        httpRequest.request(
          url, options, (err: BusinessError, data: http.HttpResponse) => {
          performanceApi.networkEventReporter()
            .url(url)
            .httpOptions(options)
            .error(err)
            .httpResponse(data)
            .report();
          if (!err) {
            // data.resultHTTP响应内容,可根据业务需要进行解析
            console.info('Result:' + JSON.stringify(data.result));
            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
          } else {
            console.error('error:' + JSON.stringify(err));
            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
          }
        });
  • HTTP数据请求场景,使用requestInStream方法发起请求。

      const reporter = performanceApi.networkEventReporter();
      let httpRequest = http.createHttp();
      httpRequest.on("headersReceive", (header: Object) => {
        reporter.responseHeader(header);
      });
      let result: ArrayBuffer[] = [];
      httpRequest.on('dataReceive', (data)=> {
        result.push(data)
      })
      httpRequest.on("dataEnd", () => {
        console.log(`result is ${buffer.from(buffer.concat(result.map(buf=>new Uint8Array(buf)))).toString()}`)
      });
    
      const options: http.HttpRequestOptions = {
        method: http.RequestMethod.GET,
        // 省略其它参数
      }
      reporter.url(url).httpOptions(options)
      httpRequest.requestInStream(
        url, options, (err: BusinessError, data: number) => {
          reporter.error(err).statusCode(data).report();
        if (!err) {
          httpRequest.off('dataReceive');
          httpRequest.off('headersReceive');
          httpRequest.off('dataEnd');
          // 当该请求使用完毕时,调用destroy方法主动销毁
          httpRequest.destroy();
        } else {
          httpRequest.off('dataReceive');
          httpRequest.off('headersReceive');
          httpRequest.off('dataEnd');
          httpRequest.destroy();
        }
      });
  • Remote Communication Kit场景。

    /**
     * 通过拦截器获取网络数据进行上报
     */
    class MyInterceptor implements rcp.Interceptor {
    
      async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
        let response: rcp.Response;
        try {
          response = await next.handle(context);
          performanceApi.networkEventReporter().rcpRequest(context.request).rcpResponse(response).report();
        } catch (e) {
          performanceApi.networkEventReporter().rcpRequest(context.request).error(e).report();
          throw e as Error;
        }
        return response;
      }
    }
    
    try {
      const request = new rcp.Request(url, "GET");
      const session = rcp.createSession({
        interceptors: [new MyInterceptor()],
        requestConfiguration: {
          tracing: {
            // 需要开启耗时统计,否则没有网络耗时数据
            collectTimeInfo: true
          }
        }
      });
      session.fetch(request).then((rep: rcp.Response) => {
        console.info(`Response succeeded: ${rep}`);
      }).catch((err: BusinessError) => {
        console.error(`Response err: Code is ${err.code}, message is ${JSON.stringify(err)}`);
      });
    } catch (e) {
      console.error(`requestRCP fail ${JSON.stringify(e)}`)
    }