鸿蒙 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
版权声明: 本文为 InfoQ 作者【auhgnixgnahz】的原创文章。
原文链接:【http://xie.infoq.cn/article/a2b4f2d68a8088766687edf8d】。文章转载请联系作者。
auhgnixgnahz
关注
还未添加个人签名 2018-07-10 加入
还未添加个人简介









评论