KMM中使用Apollo GraphQL创建数据订阅无响应问题求助
排查KMM中Apollo GraphQL订阅无响应问题
以下是针对你的订阅无法进入.collect代码块的具体排查步骤:
1. 修正代码语法错误
你的collect lambda里存在变量名错误:参数定义为item ->,但后续使用了it.data,这会导致运行时异常,直接终止协程执行,自然看不到输出。修正后代码:
suspend fun subscribing() { val mySubscription = apolloClient.subscription(SubscribeToCarSubscription()) mySubscription.toFlow() .collect { item -> println(item) println("inside sub") // 替换it为item item.data?.commandResponse?.commandName?.let { println("Command Name: $it") } } }
2. 确认WebSocket协议与后端匹配
Apollo支持两种WebSocket协议:GraphQLWsProtocol(原graphql-ws)和GraphQLTransportWsProtocol(Apollo Server 3+默认的graphql-transport-ws)。如果后端是Apollo Server,优先检查协议是否匹配:
- 若后端用
graphql-transport-ws,替换协议配置:.wsProtocol(GraphQLTransportWsProtocol.Factory())
3. 检查WebSocket依赖是否齐全
KMM项目中使用Apollo订阅必须添加WebSocket依赖,在shared模块的build.gradle.kts中确认:
dependencies { implementation("com.apollographql.apollo3:apollo-runtime:3.8.2") // 替换为你的实际版本 implementation("com.apollographql.apollo3:apollo-ws:3.8.2") // 必须添加此依赖 }
4. 添加错误捕获排查问题
当前代码未处理订阅错误,添加错误捕获可以看到连接或订阅失败的原因:
suspend fun subscribing() { val mySubscription = apolloClient.subscription(SubscribeToCarSubscription()) mySubscription.toFlow() .catch { error -> println("订阅错误:${error.message}") error.printStackTrace() } .collect { item -> println(item) println("inside sub") item.data?.commandResponse?.commandName?.let { println("Command Name: $it") } } }
5. 确保协程作用域正确
在LoginActivity中使用launch时,需绑定Activity的生命周期作用域,避免协程被意外取消:
// 导入lifecycleScope import androidx.lifecycle.lifecycleScope // 替换原launch代码 lifecycleScope.launch { repo.subscribing() }
6. 检查WebSocket连接的认证信息
如果后端订阅需要登录认证,需确保WebSocket连接时携带Token(与HTTP请求的认证方式一致):
val apolloClient = ApolloClient.Builder() .serverUrl("http://10.0.2.2:4000/graphql") .webSocketServerUrl("ws://10.0.2.2:4000/graphql") .wsProtocol(GraphQLWsProtocol.Factory( connectionPayload = { // 替换为你的实际Token获取逻辑 mapOf("Authorization" to "Bearer ${UserManager.getToken()}") } )) .build()
7. 开启Apollo日志排查连接细节
添加日志拦截器,查看WebSocket连接和订阅的完整流程:
import com.apollographql.apollo3.network.http.LoggingInterceptor import com.apollographql.apollo3.network.ws.LoggingInterceptor as WsLoggingInterceptor val apolloClient = ApolloClient.Builder() .serverUrl("http://10.0.2.2:4000/graphql") .webSocketServerUrl("ws://10.0.2.2:4000/graphql") .wsProtocol(GraphQLWsProtocol.Factory()) // 开启HTTP日志 .addHttpInterceptor(LoggingInterceptor(LoggingInterceptor.Level.BODY)) // 开启WebSocket日志 .addWebSocketInterceptor(WsLoggingInterceptor(WsLoggingInterceptor.Level.BODY)) .build()
内容的提问来源于stack exchange,提问作者Luluxlu
相关产品推荐
相关产品推荐

