前言
本文基于Api13。
之前开源过一个基于rcp,也就是基于Remote Communication Kit(远场通信服务)的网络库,自己在测试的时候没有问题,但是开源之后,就暴露了很多的问题,像post请求类型不对问题,多次请求之后就无法请求问题,header在拦截器中无法获取等等问题,这些问题的出现,主要在于未细心查看官方文档,未全面自测等产生的,为了做到日后避免再出错,索性把这些问题一一记录下来,希望可以帮助到一些朋友。
问题
一开始封装好之后,自己也做了一些测试,无问题之后就开源了,可是过了一些时间后,就接到了一个奇葩问题,说封装的这个网络库,在进行了多次请求之后,就无法请求问题。
当时我都差异了,无法请求是什么问题,为什么会多次请求之后才会报出这样的问题?带着这个疑问,我运行了自己的Demo,开始测试。
无论是get请求还是post请求,还是其他请求方式,我都进行了测试,在尝试多次之后,没发现问题啊,请求都是正常的,数据也能正常返回,难道,这个小伙子在耍我?
不太可能,谁会拿着问题在耍人,再说了能提出问题的人,绝对是忠实的粉丝,可是为什么,他的问题,我复现不出来呢?可能我的请求不够多?
于是,我就开始了一次又一次的请求,盯着日志控制台,一次,两次,直到第十七次,结果未返回,也未报错,这时,我才惊讶的发现,果然有这个问题,差点冤枉了好人。
不应该啊,我都是按照官方的案例进行封装的,难道是官方的问题,于是我重新查看了官方文档,随便找了一个案例,进行运行。
这里接口就不写了,大家随便找一个接口就行。
TypeScript
private tempNumber: number = 0
private doHttp() {
// 定义sessionConfig对象
const sessionConfig: rcp.SessionConfiguration = {
requestConfiguration: {
transfer: {
autoRedirect: true,
timeout: {
connectMs: 10000,
transferMs: 10000
}
},
tracing: {
verbose: true
}
}
}
// 创建通信会话对象
const session = rcp.createSession(sessionConfig)
// 定义请求对象rep
let req = new rcp.Request('xxx', 'GET')
// 发起请求
this.tempNumber++
session.fetch(req).then((response) => {
console.log("===第"+this.tempNumber+"次请求:" + response.toString())
}).catch((err: BusinessError) => {
console.log("=======ERROR:" + err.message)
})
}
运行之后,果然也会出现以上的问题,查看日志控制台后,发现,超过16次,直接会下面的异常错误信息:
这我也分析不出来啊,当我正要给官方提工单的时候,一个说明映入了眼帘,rcp目前只能创建16个session实例, 这也就是为什么,前16次请求都没问题的原因。
如何解决
怎么着?只能让发起16次请求呗,这显然不合理啊,一个项目也不止16个请求啊,仔细再回头看下官方案例,好像发起请求也不是通过session啊,而是最终通过Request,好像是我误解了官方,好尴尬。
解决也很简单,那就是复用session,并提供可重新创建session的功能,这样就可以解决每次创建session造成的大于16次问题。
还是以上的代码案例,我们简单做下处理:
TypeScript
private tempNumber: number = 0
private mSession?: rcp.Session = undefined
private doHttp() {
// 定义sessionConfig对象
const sessionConfig: rcp.SessionConfiguration = {
requestConfiguration: {
transfer: {
autoRedirect: true,
timeout: {
connectMs: 10000,
transferMs: 10000
}
},
tracing: {
verbose: true
}
}
}
// 创建通信会话对象
if (this.mSession == undefined) {
this.mSession = rcp.createSession(sessionConfig)
}
// 定义请求对象rep
let req = new rcp.Request('xxx', 'GET')
// 发起请求
this.tempNumber++
this.mSession.fetch(req).then((response) => {
console.log("===第" + this.tempNumber + "次请求:" + response.toString())
}).catch((err: BusinessError) => {
console.log("=======ERROR:" + err.message)
})
}
可以看到,就不会有超过16次的问题了。
注意事项
在实际的网络库封装中,我们不能以简单的方式进行处理,毕竟考虑的问题有很多,比如,我需要重新创建会话怎么办?重新创建了会话,如何保证,某些请求使用第一个会话,某些请求使用第二个会话,这些问题都是必须要考虑的。
建议以map集合的方式,存储当前创建的会话,给每一个新的会话都标识一个唯一的key,这样就可以区分请求使用指定会话问题。
至于是否要重新创建会话,通过传递参数即可。
相关总结
总体来说,问题倒不是很大,解决起来也不是很麻烦,所以啊,老铁们,在实际的开发中,对于一些官方文档,还是建议多看,这样可以提前避免后续的不必要麻烦。
还有一种比较消耗资源的方式解决这个问题,那就是每次请求之后,直接关闭会话,但是一个项目中会有N个请求,每次执行请求都要创建关闭......,当然了这个自己衡量。