写点什么

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

作者:auhgnixgnahz
  • 2025-06-23
    北京
  • 本文字数:4124 字

    阅读完需:约 14 分钟

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



接下来通过登录的例子对比一下 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; });}</responseresult>
复制代码


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; });}</responseresult>
复制代码


定义的一个 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); }}</rcp.response>
复制代码


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



以上是两种网络请求的配置,以下是使用,贴一下 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('网络异常'); }); }) }}</userbean>
复制代码


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


@ObservedV2export 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) }) }) }}</userviewmodel></boolean>
复制代码


page 页面请求监听


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


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


发布于: 刚刚阅读数: 2
用户头像

auhgnixgnahz

关注

还未添加个人签名 2018-07-10 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙Next网络请求HTTP和RCP的使用和对比_鸿蒙Next_auhgnixgnahz_InfoQ写作社区