背景
挪动 app 中展现的数据少数都是通过服务器接口获取的,当接口数据与用户相干时,服务端接口会要求客户端把用户信息通过接口发送到服务器。广泛的做法是把用户登录后的 token 数据发送给服务器的接口。思考到平安问题,token 都有过期工夫,token 过期后服务端就不能通过这个 token 查问用户的具体信息了。为了刷新过期 token,服务端会提供一个刷新 token 的接口给客户端应用。
问题剖析
因为要求上传 token 的服务端接口会有很多,所以这些接口的调用都须要思考 token 过期生效问题。
这些接口调用的异样解决中须要减少 token 过期解决,在 token 过期的状况下触发 token 刷新解决。
token 刷新后触发接口的重试申请。
如何应用 flow 实现
首先咱们实现一个刷新 token 的 flow。
private val refreshTokenFlow = flow {if (expiredToken) {cachedToken = serverApi.refreshToken("token-0")
expiredToken = false
}
emit(cachedToken)
}
expiredToken 变量代表 token 是否过期,理论开发过程中这个变量的值应该依据过期工夫计算得出的。cachedToken 变量保留着最新的 token 值,申请用户相干信息的接口时能够把这个 token 传递给服务端用于查问。咱们能够看到 cachedToken 的值是通过调用服务端提供的刷新接口获取的。这个 flow 最终发射的是最新的 token 值,同时咱们也看到这个 flow 调用刷新接口的逻辑只有 token 过期时才会被调用。
第二步定义申请用户相干数据的 flow
private fun getDataFlow(token: String) = flow {emit(serverApi.getDataViaToken(token))
}
因为申请用户数据的接口依赖 token 的值,所以这个 flow 是通过办法生成的。flow 的生成也比较简单,它间接调用服务端的接口并将数据发射进来。
第三步将刷新 token 的 flow 和申请用户数据的 flow 开展
private val userDataFlow = refreshTokenFlow.flatMapConcat{token->
getDataFlow(token)
}
flatMapConcat 办法将后面定义的两个流拼接在一起,这时咱们要是收集拼接后的 userDataFlow,refreshTokenFlow 会被收集,flatMapConcat 办法接管到 refreshTokenFlow 发射的 token 后开始收集 getDataFlow 办法返回的 flow。这样连个 flow 的依赖关系通过 flatMapConcat 完满实现了。
第四步实现 token 过期重试机制
private val userDataFlow = refreshTokenFlow.flatMapConcat{token->
getDataFlow(token)
}.retryWhen { cause, attempt ->
if (attempt > 1) {false} else if(cause is InvalidTokenException) {
expiredToken = true
true
}else{false}
}.catch {msgView.text = it.message}
基于第三步的 flow 拼接咱们增加了 retryWhen 和 cach 两个块。retryWhen 块用于实现重试机制,参数 cause 是后面流程产生的异样,参数 attempt 代表重试的次数,返回值 true 代表进行重试,返回值 false 代表不进行重试。在 retryWhen 块中咱们能够通过 cause 的类型来判断是否要重试,当 cause 为 InvalidTokenException 时代表 token 过期,所以进行重试并且重置了 token 过期 expiredToken。为了防止有限地进行重试,这里限度重试次数为一次。catch 块解决不进行重试时的逻辑,个别会将出错的信息显示到界面上。
总结
通过 flow 的形式实现 token 刷新机制相较于传统的形式有如下劣势:
逻辑简单明了,刷新流程简略清晰直观。flow 操作符语义简单明了,链式的形式申明处理过程更容易了解,没有简单的嵌套。
通过申明的形式定义了刷新流程,同时也反对通过申明的形式扩大已有流程。比方这里拼接了刷新 token 的 flow 和获取用户数据的 flow。
重试机制能够依据不同的依赖 token 接口进行定制解决,接口的重试机制更加灵便不便。这里没有针对重试流程定义新的 flow,但在理论利用中咱们能够为重试流程定义 flow,而后将 flow 拼接在已有 flow 后。这样咱们能够在不同的中央重用重试流程的 flow。
我的公众号曾经开明,公众号会同步公布。
欢送关注我的公众号
————————————————
版权申明:本文为 CSDN 博主「mjlong123123」的原创文章,遵循 CC 4.0 BY-SA 版权协定,转载请附上原文出处链接及本申明。
原文链接:https://blog.csdn.net/mjlong1…