android - kotlin 中的通用 grpc 请求

标签 android kotlin grpc kotlin-coroutines grpc-java

class API {

    val nonBlockingStub: HealthcareAPIGrpc.HealthcareAPIStub //Generated Java GRPC Stub

    suspend fun exampleRequest(params: Params) : ReturnedResult = suspendCancellableCoroutine { routine ->
        val obs = object : StreamObserver<ReturnedResult> {
            override fun onNext(value: ReturnedResult?) {
                routine.resume(value!!)
            }

            override fun onError(t: Throwable?) {
                routine.resumeWithException(t!!)
            }

            override fun onCompleted() {
            }
        }
        nonBlockingStub.exampleRequest(params, obs)
    }
}

所以我正在开发一个 Kotlin android 应用程序,它有一个用 java 生成的 grpc 客户端。最近我不得不移动所有 API 请求以使用 kotlin 协程。对于每个请求,我都必须复制粘贴这个 exampleRequest 函数。

我很好奇是否可以创建一个通用函数来执行此操作,接受一些参数并调用底层 stub 函数

最佳答案

理想情况下,应该有一个 stub 生成器生成适当的调用,如 suspend/Flow方法,但您仍然可以使用专用的辅助函数抽象大部分转换:

fun <T> grpcFlow(
    @BuilderInference block: suspend (StreamObserver<T>) -> Unit
): Flow<T> = callbackFlow {
    // Use ClientCallStreamObserver to support cancellation
    val observer = object : ClientCallStreamObserver<T>() {
        override fun onNext(value: T) {
            sendBlocking(value)
        }

        override fun onError(t: Throwable) {
            cancel(CancellationException("GRPC Error", t))
        }

        override fun onCompleted() = channel.close()
    }

    block(observer)

    awaitClose { 
        observer.cancel("flow cancellation", null)
    }
}

然后你的 API 就变成了:

class API {
    val nonBlockingStub: HealthcareAPIGrpc.HealthcareAPIStub

    suspend fun exampleRequest(params: Params) = grpcFlow {
        // @BuilderInference should ensure the correct type is used
        nonBlockingStub.exampleRequest(params, it)
    }.single() // Since we only expect a single response value.

    // And for returns (stream ReturnedResult)
    suspend fun exampleStreamingRequest(params: Params) = gcpcFlow {
        nonBlockingStub.exampleStreamingRequest(params, it)
    } // Flow<ReturnedResult>

}

关于android - kotlin 中的通用 grpc 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61235338/

相关文章:

Android Canvas 矩形改变颜色

android - 在 gradle 中重构 Maven block

java - 如何在 Kotlin/Java 中将 LocalDate 转换为 Long

java - 如何迭代由 firebase 随机生成的不同键值

asynchronous - gRPC future 回调出现异常 :StatusRuntimeException: CANCELLED

image - 通过 goRPC 发送和图像

amazon-web-services - 如何解决这个 gRPC 安装问题?

android - Android 操作系统上的 TEE/HSM 支持

android - 从服务器 [DF-AA-20] 检索信息时发生应用内购买错误

android - 如何在 Android Jetpack Compose 的 TabRow 中更改按下的 Tab 颜色?