当前位置: 首页 > 知识库问答 >
问题:

如何逐个usnig rx和kotlin请求调用远程服务?

华昕
2023-03-14

我有应用程序必须向其发送数据的远程服务:改造中的定义2:

interface FooRemoteService {
    @POST("/foos")
    fun postFoos(@Body foos: List<FooPojo>): Observable<Response<List<String>>
 }

但是该调用一次的限制不超过X Foo。每个调用可以返回206个代码“部分成功”,其中包含不成功上传的Foo列表。还有413个“请求实体太大”。当然还有400和500。

并且应用程序需要发送未知数量的foo项目(由用户在运行时定义)。

为了避免服务应用程序的DDoS,需要一个接一个地发送此调用。

所以我在我的FooRepositoryImpl中实现了这样的功能:

这是一个想法。我对下面的解决方案不满意,我相信它可以做得更好,但我已经没有主意了。有什么建议吗?

override fun postFoos(foos: List<Foo>) Completable {
  val fooChunks = divideListInToChuncksUnderRequestLimit(foos)

  val unuploadedFoos = mutableListOf<UnuploadedFoo>()
  fooChunks.fold(unuploadedFoos) 
  { accu: MutableList<UnuploadedFoo>, chunk ->
     fooRemoteService
        .postFoos(chunk)
        .subscribeOn(Schedulers.io())
        .flatMapCompletable {
             if (it.isSuccessful) {
                         Completable.complete()
                    } else {
                        Timber.e("$it")
                       accu.add(it.body())

                    }
                }.blockingAwait()
        responses

  }
return Completable.complete()
}

在最后,应用程序应该显示所有不成功的fos的列表,或者如果有可用的。所以我需要从未上传的fos的功能列表中传递。

共有1个答案

盖成弘
2023-03-14

如果您可以稍微修改一下postFoos的返回类型,那么类似的操作可能会奏效:

override fun postFoos(foos: List<Foo>): Observable<List<UnuploadedFoo>> {
    val chunks = foos.chunked(CHUNK_SIZE)
    val posters = chunks.map { chunk ->
        fooRemoteService.postFoos(chunk)
                .map { response ->
                    response.unUploaded.takeIf { !response.isSuccessful } ?: emptyList()
                }
                .filter { it.isNotEmpty() }
                .toObservable()
    }

    return Observable.concatDelayError(posters)
}

我想象你的服务有这样的东西:

data class Response(val isSuccessful: Boolean, val unUploaded: List<UnoploadedFoo>)

fun postFoos(foos: List<Foo>): Single<Response>

这里的诀窍在于:

(...) 等待订阅传递给它的每个附加可观察对象,直到前一个可观察对象完成。

 类似资料:
  • 我在测试在kotlin的协程里使用网络io是否会导致线程阻塞 测速结果是InputStream.read确实导致线程阻塞了,而不是挂起。 那么运行在统一个线程下的其他协程也不能运行了,我知道可以使用 这些方式把网络请求放入其他线程 但是我想知道的是如果这两个协程都必须运行在同一个线程里时,是否可以通过修改代码(比如异步io等方式)确保第一个协程能每秒打印一次,第二个协程能在接收到数据时及时打印。

  • 问题内容: 我需要通过Ajax向远程域发出POST请求,我知道Same-Origin Policy的限制,但我读过,有可能在服务器上的PHP中建立网桥以转发请求。 事实是我不知道如何编写此桥,也无法在Google上找到信息。 我想我需要使用CURL。 有人可以解释一下我怎么写吗? 问题答案: 如果需要代理服务器或“ Bridge ”,则可以尝试以下操作:您可以实现对该PHP脚本的简单AJAX调用,

  • 主要内容:1.概述,2. HttpClientConnection,3. HessianProtocol1.概述 Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。 本文涉及类图(红圈部分)如下: 2. HttpClientConnection 实现 HessianConnection 接口,HttpClient 连接器实现类。 2.1 HttpClientConnec

  • 主要内容:1. 概述,2. AbstractProxyProtocol,3. HttpProtocol1. 概述 基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现 涉及类图(红圈部分)如下: 2. AbstractProxyProtocol 现 AbstractProtocol 抽象类,Proxy 协议抽象类。为 HttpProtocol 、RestProtocol 等子类,提供公用的服务暴露、服务引用的公用方法,同时定义了如下抽象方法,用于不同子类协议实

  • 在终端上,我得到了这个错误:$./asadmin start-domain domain1 找不到默认的域目录。此系统属性没有值:com.sun.aas.domainsroot命令启动-域失败。 在Eclipse上,我得到了这个运行时异常:在Felix平台上启动GlassFish 玻璃鱼4 拜托,你知道怎么解决这个问题吗?

  • 本文向大家介绍Android中如何利用AIDL机制调用远程服务,包括了Android中如何利用AIDL机制调用远程服务的使用技巧和注意事项,需要的朋友参考一下 在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然, Java中是不支持跨进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。在JavaEE