鸿蒙 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 层代码,返回登录成功或失败即可
@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)
})
})
}
}
</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 加入
还未添加个人简介
评论