加入我们,于10月8日至10日在纽约市,了解关于 GraphQL 联邦和 API 平台工程的最新技巧、趋势和新闻。参加2024年在纽约市的 GraphQL 峰会
文档
免费开始

11. 编写您的第一个订阅


在本节中,您将使用订阅功能,以便在有人预订航班🚀时接收通知!订阅 允许在服务器上的事件发生时实时接收通知。 后端 基于 基于 WebSocket

编写您的订阅

打开您的 沙盒,点击左侧的 Schema 选项卡。除了 查询突变,您将看到一个第类型的根字段订阅。单击订阅以查看tripsBooked字段

The definition of tripsBooked in the schema

字段不接受任何并返回一个名为tripsBooked的单个。由于您可以一次性预订多个行程,因此tripsBooked是一个Int。它将包含一次性预订的行程数或行程被取消时的-1。

单击tripsBooked左边的播放按钮以在探索器中打开该字段。打开一个新标签页,然后检查tripsBooked旁边的加号按钮以添加该字段:

The initial definition of the TripsBooked subscription

再次重命名您的,以便更容易找到:

The subscription after rename

单击操作按钮,您的订阅将开始侦听事件。您可以告诉它正在运行,因为将在左下角弹出一个面板,其中将显示订阅数据:

The UI showing that it's listening for subscription updates

测试您的订阅

在探索器中打开一个新标签页。在这个新标签页中,添加一段代码来预订行程,类似于第9步,但带有硬编码的ID:

mutation BookTrip {
bookTrips(launchIds: ["93"]){
message
}
}

请确保包含身份验证头。在添加的Sandbox Explorer面板的底部,有一个Headers部分:

Adding a login token to explorer

点击“提交 操作按钮。如果一切顺利,你已经预订了旅行!在右侧面板的顶部,你会看到你 BookTrip 的成功JSON,下面是TripsBooked 订阅的更新JSON:

Subscription success in Explorer

继续预订和/或取消旅程,你将实时看到发生在订阅面板中的事件。一段时间后,服务器可能会关闭连接,你必须重新启动你的订阅以继续接收事件。

将订阅添加到项目中

现在你的订阅正在运行,将其添加到你的项目中。创建一个名为TripsBooked.graphql的文件,放在schema.graphqls和你的其他文件旁边,并将订阅的内容粘贴进去。这个过程与你在查询和时所做的类似:

app/src/main/graphql/TripsBooked.graphql
subscription TripsBooked {
tripsBooked
}

配置ApolloClient以使用订阅

本教程使用subscriptions-transport-ws 协议进行订阅。关于全新graphql-ws 或 Appsync等更多选项,请查看GraphQL通过WebSocket协议

Apollo.kt中,为你的 ApolloClient 配置一个 webSocketServerUrl:

Apollo.kt
val apolloClient = ApolloClient.Builder()
.serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
.webSocketServerUrl("wss://apollo-fullstack-tutorial.herokuapp.com/graphql")
.okHttpClient(...)
.build()

wss:// 是WebSocket的协议。

在预定或取消旅行时显示Snackbar

MainActivity中,注册你的订阅并保留返回的协程Flow的引用。

使用collectAsState以获取Flow的最新值作为状态。当Flow发出值时,该值将存储在tripBookedResponse中,并由依赖于它的LaunchedEffect触发UI的重构。

MainActivity.kt
RocketReserverTheme {
val tripBookedFlow = remember { apolloClient.subscription(TripsBookedSubscription()).toFlow() }
val tripBookedResponse: ApolloResponse<TripsBookedSubscription.Data>? by tripBookedFlow.collectAsState(initial = null)
LaunchedEffect(tripBookedResponse) {
if (tripBookedResponse == null) return@LaunchedEffect
val message = when (tripBookedResponse!!.data?.tripsBooked) {
null -> "Subscription error"
-1 -> "Trip cancelled"
else -> "Trip booked! 🚀"
}
// TODO use the message
}

现在让我们在Material SnackBar中显示信息。

为此,您需要创建一个SnackbarHostState并在其上调用showSnackbar。不要忘记将其传递到下面的Scaffold中:

MainActivity.kt
val snackbarHostState = remember { SnackbarHostState() }
val tripBookedFlow = (...)
(...)
val message = (...)
snackbarHostState.showSnackbar(
message = message,
duration = SnackbarDuration.Short
)
}
Scaffold(
topBar = { TopAppBar({ Text(stringResource(R.string.app_name)) }) },
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues ->

处理错误

就像查询和mutations一样,如果连接丢失或发生其他协议错误,订阅将引发错误。要处理这些情况,您可以配置客户端使用webSocketReopenWhen函数重试订阅。返回true以重试,返回false以停止。为了避免过于频繁的重试,您可以使用attempt参数来延迟重试:

Apollo.kt
val apolloClient = ApolloClient.Builder()
(...)
.webSocketReopenWhen { throwable, attempt ->
Log.d("Apollo", "WebSocket got disconnected, reopening after a delay", throwable)
delay(attempt * 1000)
true
}

测试您的代码

构建并运行您的应用,然后回到Sandbox Explorer,选择您设置BookTrip突变选项卡的标签页。当您的应用打开时预订新行程,你应该看到一个Snackbar 🚀

A trip has been booked

本教程到此结束,恭喜!🎉

更多资源

使用本文档的其余部分了解更多高级主题,如缓存Gradle配置

上一页
10. 验证您的操作
下一页
Gradle插件配置
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,即Apollo GraphQL。

隐私政策

公司