android - Android GRPC 客户端 http 调用错误 io.grpc.StatusException: UNAVAILABLE: End of stream or IOException
问题描述
问候,
我想知道在后端调用使用 NodeJS 构建的 GRPC 服务并使用 Repl.it 部署到 Internet 时如何解决以下异常。以下是我在 ui 测试期间收到的消息:
io.grpc.StatusException: UNAVAILABLE: End of stream or IOException
at io.grpc.Status.asException(Status.java:550)
at io.grpc.kotlin.ClientCalls$rpcImpl$1$1$1.onClose(ClientCalls.kt:289)
at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:464)
at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:428)
at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:461)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:553)
at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:68)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:739)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:718)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
##Context: ## 我目前在一个 android 应用程序中工作,我尝试在后端和移动客户端中实现 GRPC 功能,在 Android 端,我使用 protobuf-gradle-plugin 设置了 grpc 客户端,库如grpc-stub、grpc-java、grpc-kotlin 和 Android Studio 中存在的 protobuff 插件。
提到的 gradle 插件和库已经为 proto 文件生成了客户端类,对于后端,我已经使用官方库实现了 grpc 服务,确保使用 0.0.0.0 公开该服务并且它可以工作使用 nodejs 客户端连接到它时。
/* grpc server service setup and running */
/* ... definitions and proto file loading ... */
function main() {
let server = new grpc.Server();
server.addService(placesProto.PlacesService.service, {
List: placesEndpoint.List
});
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.start();
console.log('grpc server running at {0.0.0.0:50051}');
}
main();
/* remote data source using the generated grpc service client*/
class DataSource {
private val channel: ManagedChannel =
ManagedChannelBuilder.forAddress(BuildConfig.GRPC_API_HOSTNAME, BuildConfig.GRPC_API_PORT)
.idleTimeout(30, TimeUnit.SECONDS).usePlaintext().build()
private val client: PlacesServiceGrpcKt.PlacesServiceCoroutineStub =
PlacesServiceGrpcKt.PlacesServiceCoroutineStub(channel)
suspend fun fetchPlaces(): Flow<AppResult<List<VisitablePlace>>> = flow {
val response: PlacesListResponse = client.list(PlacesListRequest.getDefaultInstance())
emit(when {
response.placesList.isNotEmpty() -> {
val visitablePlaces: List<VisitablePlace> =
response.placesList.mapNotNull { VisitablePlace(it) }
AppResult.Success(visitablePlaces)
}
else -> {
AppResult.Error(Exception("Places list not available."))
}
})
}
}
值得一提的是:
- 我将 Repl.it 用于 nodejs 后端,因为从那里开发和提供 Web 应用程序很容易,在这部分,我已经从那里使用 javascript 测试了服务,这个想法是了解如何解决之间的连接他们,在 kotlin 代码片段中,我使用 grpc 客户端库中提供的类:S
- 我使用物理设备(不是模拟器)进行测试
此致,
解决方案
推荐阅读
- javascript - 访问json中的嵌套数组
- regex - 正则表达式查找仅包含数字的字符串,但仅在以 # 或 \s 开头且后跟空格时匹配
- c# - 导入文件后从字符串中删除多余字符
- c++ - 如何通过动态规划方法解决这个问题?
- javascript - 在生成多个灯塔报告时,我可以在不提供目录路径的情况下获得灯塔报告的正确名称吗?
- java - Hibernate 在使用 @GeneratedValue(strategy=GenerationType.AUTO) 时不保存对象
- pdf - 强加(nup'ped)PDF 文件不允许选择文本
- acumatica - 如何通过代码操作审核屏幕 (SM205510)
- python - 仅在按下某个按钮时才打开文件目录,而不是自动打开
- bash - 从列表中查找一个目录中的文件,复制到新目录,然后执行脚本