鸿蒙Next网络请求HTTP和RCP的使用和对比

2025-06-27 22:45:59
104次阅读
0个评论

RCP指的是远程通信平台(remote communication platform),RCP提供了网络数据请求功能,相较于Network Kit中HTTP请求能力,RCP更具易用性,且拥有更多的功能。在开发过程中,如果有些场景使用Network Kit中HTTP请求能力达不到预期或无法实现,那么就可以尝试使用RCP中的数据请求功能来实现。以下贴一部分对比截图,详细可以关注官方文档。 对比.png 接下来通过登录的例子对比一下HTTP和RCP的写法和参数设置 ####HTTP:

//网络请求工具类
export function httpRequestPost(url: string, params: object) {
  return httpRequest(url, http.RequestMethod.POST, params);
}

function httpRequest(url: string, method: http.RequestMethod, params?: object): Promise<ResponseResult> {
  let httpRequest = http.createHttp();
  let user :UserBean = sp_get(ApiConstants.SP_USER,UserBean) as UserBean
  let tenantId = user.tenantId??''
  let responseResult = httpRequest.request(url, {
    method: method,
    readTimeout: Constants.HTTP_READ_TIMEOUT,
    header: {
      'Content-Type': ContentType.JSON,
      'APPLICATION-ID':'2',
      'IOT-TENANT-KEY':sp_get(ApiConstants.LOGIN_TYPE,Boolean)?'{"tenantId":"'+tenantId+'"}':'',
      'Authorization':sp_get(ApiConstants.LOGIN_TYPE,Boolean)?'Bearer '+user.access_token??'':''
    },
    connectTimeout: Constants.HTTP_READ_TIMEOUT,
    extraData: params
  });
  let serverData = new ResponseResult();
  return responseResult.then((value: http.HttpResponse) => {
    if (value.responseCode === HttpConfig.HTTP_CODE_200) {
      let result = `${value.result}`;
      let resultJson: ResponseResult = JSON.parse(result);

      if (null!=resultJson.data) {
        serverData.code = HttpConfig.SERVER_CODE_SUCCESS;
        serverData.data = resultJson.data;
      }
      if (null != resultJson.error) {
        serverData.code = HttpConfig.SERVER_CODE_ERROR;
        serverData.error  = resultJson.error;
        serverData.msg = resultJson.msg;
      }
    } else {
      serverData.msg = `请求失败,请重试!`;
    }
    return serverData;
  }).catch(() => {
    serverData.msg ="请求失败,请重试!";
    return serverData;
  });
}

HTTP的全局配置

export default class HttpConfig {
  static readonly SERVER_CODE_SUCCESS: string = 'success';
  static readonly SERVER_CODE_ERROR: string = 'error';
  static readonly HTTP_READ_TIMEOUT: number = 10000;
  static readonly HTTP_CODE_200: number = 200;
}

/**
 * The refresh state enum.
 */
export const enum RefreshState {
  DropDown = 0,
  Release = 1,
  Refreshing = 2,
  Success = 3,
  Fail = 4
}

/**
 * The newsList state enum.
 */
export const enum PageState {
  Loading = 0,
  Success = 1,
  Fail = 2
}

/**
 * The file upload state enum.
 */
export const enum UploadingState {
  COMPLETE = 'complete',
  FAIL = 'fail'
}

/**
 * The request method enum.
 */
export const enum RequestMethod {
  POST = 'POST',
  GET = 'GET'
}

/**
 * The request content type enum.
 */
export const enum ContentType {
  JSON = 'application/json',
  FORM = 'multipart/form-data'
}

####RCP:


// 定义请求头
let headers: rcp.RequestHeaders = {
  "Content-Type": "application/json"
};
const sessionConfig: rcp.SessionConfiguration = {
  requestConfiguration: {
    transfer: {
      autoRedirect: true,//HTTP重定向
      maxAutoRedirects:10,//最大重定向次数,默认50
      timeout: {
        connectMs: 5000, //允许建立连接的最长时间(以毫秒为单位)
        transferMs: 10000, //允许传输数据的最长时间 (以毫秒为单位)
        inactivityMs:30000 //允许在没有数据传输或连接活动的情况下,允许的最长时间
      }
    },
    tracing: { //捕获详细的跟踪信息
      verbose: true
    }
  },
  baseAddress: ApiConstants.SERVER,
  interceptors: [new TokenInterceptor()],
  headers: {},
  cookies: {},
  connectionConfiguration:{
    maxConnectionsPerHost : 6, //单个主机允许的最大并发 TCP 连接数
    maxTotalConnections : 64  //此会话中允许的最大同时 TCP 连接总数
  },
  sessionListener: {
    onCanceled: () => console.info("Session was cancelled"),
    onClosed: () => console.info("Session was closed")
  }
};

const session = rcp.createSession(sessionConfig);


export function rcpRequest(url: string, params: object): Promise<ResponseResult> {
  let req = new rcp.Request(url, 'POST', headers, params);
  let serverData = new ResponseResult();
  return session.fetch(req).then((value) => {
    if (value.statusCode === HttpConfig.HTTP_CODE_200) {
      let result = `${JSON.stringify(value)}`;
      let resultJson: ResponseResult = JSON.parse(result);

      if (null != resultJson.data) {
        serverData.code = HttpConfig.SERVER_CODE_SUCCESS;
        serverData.data = resultJson.data;
      }
      if (null != resultJson.error) {
        serverData.code = HttpConfig.SERVER_CODE_ERROR;
        serverData.error = resultJson.error;
        serverData.msg = resultJson.msg;
      }
    } else {
      serverData.msg = `请求失败,请重试!`;
    }
    return serverData;
  }).catch((err: BusinessError) => {
    serverData.msg = "请求失败,请重试!";
    return serverData;
  });
}

定义的一个token请求拦截器:

export class TokenInterceptor implements rcp.Interceptor {

  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    let user :UserBean = sp_get(ApiConstants.SP_USER,UserBean) as UserBean
    let tenantId = user.tenantId??''
      context.request.headers={
        'APPLICATION-ID':'2',
        'IOT-TENANT-KEY':sp_get(ApiConstants.LOGIN_TYPE,Boolean)?'{"tenantId":"'+tenantId+'"}':'',
        'Authorization':sp_get(ApiConstants.LOGIN_TYPE,Boolean)?'Bearer '+user.access_token??'':''
      }
    return next.handle(context);
  }
}

通过debug可以看到,添加的拦截器加入了自定义的headers 拦截器.png

以上是两种网络请求的配置,以下是使用,贴一下model层代码: 使用httpRequestPost或者rcpRequest都可以登录成功,返回的是一样的,所以viewModel层不需要修改

export class UserBean {
  access_token : string = ""
  deviceId : string= ""
  deviceName : string= ""
  latitude : string= ""
  longitude : string= ""
  mineId : string= ""
  refresh_token : string= ""
  tenantId : string= ""
  token_type: string = ""
  user_id : string= ""
  userName : string= ""
  isLogin:boolean = false;

  getLogin(login:LoginReqBean) :Promise<UserBean>{
    return new Promise((resolve:Function, reject: Function)=>{
      // let url = ApiConstants.SERVER+ApiConstants.LOGIN;
      // httpRequestPost(url,login).then((result:ResponseResult)=>{
      //   if (result && result.code === HttpConfig.SERVER_CODE_SUCCESS) {
      //     resolve(result.data);
      //   } else if (result.code === HttpConfig.SERVER_CODE_ERROR){
      //     reject(result.error?.message);
      //   }else {
      //     reject(result.msg)
      //   }
      // }).catch((err:Error)=>{
      //   reject('网络异常');
      // });
      rcpRequest(ApiConstants.LOGIN,login).then((result:ResponseResult)=>{
        if (result && result.code === HttpConfig.SERVER_CODE_SUCCESS) {
          resolve(result.data);
        } else if (result.code === HttpConfig.SERVER_CODE_ERROR){
          reject(result.error?.message);
        }else {
          reject(result.msg)
        }
      }).catch((err:Error)=>{
        reject('网络异常');
      });
    })
  }
}

viewModel层代码,返回登录成功或失败即可

@ObservedV2
export default class LoginViewModel {
  @Trace userViewModel: UserViewModel = new UserViewModel();
  @Trace isLogin: boolean = false
  @Trace msg: string = ''

  login(loginBean: LoginReqBean): Promise<boolean> {
    return new Promise((resolve: Function, reject: Function) => {
      let userbean = new UserBean();
      userbean.getLogin(loginBean).then((user: UserBean) => {
        sp_put(ApiConstants.SP_USER,user)
        this.userViewModel = UIUtils.makeObserved<UserViewModel>(user as UserViewModel) as UserViewModel
        this.isLogin = true
        resolve(true)
      }).catch((msg: string) => {
        this.msg = msg
        this.isLogin = false
        resolve(false)
      })
    })
  }
}

page页面请求监听

await  this.loginViewModel.login(loginReq).then((res:boolean)=>{
            if (res) {
             //登录成功,跳转到下个页面
            }else {
            //登录失败
              showToast(this.loginViewModel.msg)
            }
          })

以上就是两种网络请求方式的简单对比,后续继续探索一下RCP的使用,有问题欢迎在评论区留言,大家一起探讨!

收藏00

登录 后评论。没有帐号? 注册 一个。