本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用中的过滤器取消订阅 WebSocket 连接 AWS AppSync
在中 AWS AppSync,您可以根据特定的筛选逻辑强制取消订阅并关闭(使 WebSocket连接失效)来自已连接客户端的连接。这在与授权相关的场景中非常有用,例如,在您从组中删除用户时。
订阅失效是针对变更中定义的负载做出的响应。我们建议您将用于使订阅连接失效的变更视为 API 中的管理操作,并仅限管理员用户、组或后端服务使用这些变更以相应地设置其权限范围。例如,使用架构授权指令,例如 @aws_auth(cognito_groups:
["Administrators"])
或 @aws_iam
。有关更多信息,请参阅使用其他授权模式。
失效筛选条件使用与增强订阅筛选条件相同的语法和逻辑。请使用以下实用程序定义这些筛选条件:
-
extensions.invalidateSubscriptions()
- 在变更的 GraphQL 解析器响应处理程序中定义。 -
extensions.setSubscriptionInvalidationFilter()
- 在链接到变更的订阅的 GraphQL 解析器响应处理程序中定义。
有关失效筛选扩展插件的更多信息,请参阅JavaScript 解析器概述。
使用订阅失效
要查看订阅失效的工作原理 AWS AppSync,请使用以下 GraphQL 架构:
type User { userId: ID! groupId: ID! } type Group { groupId: ID! name: String! members: [ID!]! } type GroupMessage { userId: ID! groupId: ID! message: String! } type Mutation { createGroupMessage(userId: ID!, groupId : ID!, message: String!): GroupMessage removeUserFromGroup(userId: ID!, groupId : ID!) : User @aws_iam } type Subscription { onGroupMessageCreated(userId: ID!, groupId : ID!): GroupMessage @aws_subscribe(mutations: ["createGroupMessage"]) } type Query { none: String }
在 removeUserFromGroup
变更解析器代码中定义失效筛选条件:
import { extensions } from '@aws-appsync/utils'; export function request(ctx) { return { payload: null }; } export function response(ctx) { const { userId, groupId } = ctx.args; extensions.invalidateSubscriptions({ subscriptionField: 'onGroupMessageCreated', payload: { userId, groupId }, }); return { userId, groupId }; }
在调用变更时,payload
对象中定义的数据用于取消订阅 subscriptionField
中定义的订阅。还会在 onGroupMessageCreated
订阅的响应映射模板中定义一个失效筛选条件。
如果extensions.invalidateSubscriptions()
有效负载包含与过滤器中定义的 IDs来自已订阅客户端的 ID 相匹配,则相应的订阅将被取消订阅。此外, WebSocket 连接已关闭。定义 onGroupMessageCreated
订阅的订阅解析器代码:
import { util, extensions } from '@aws-appsync/utils'; export function request(ctx) { // simplfy return null for the payload return { payload: null }; } export function response(ctx) { const filter = { groupId: { eq: ctx.args.groupId } }; extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter)); const invalidation = { groupId: { eq: ctx.args.groupId }, userId: { eq: ctx.args.userId } }; extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation)); return null; }
请注意,订阅响应处理程序可以同时定义订阅筛选条件和失效筛选条件。
例如,假设客户端 A 使用以下订阅请求为具有 ID
的新用户订阅具有 ID user-1
的组:group-1
onGroupMessageCreated(userId : "
user-1
", groupId: :"group-1
"){...}
AWS AppSync 运行订阅解析器,该解析器生成前面的onGroupMessageCreated
响应映射模板中定义的订阅和失效过滤器。对于客户端 A,订阅筛选条件仅允许将数据发送到
,并为 group-1
和 user-1
定义了失效筛选条件。group-1
现在假设客户端 B 使用以下订阅请求为具有 ID
的用户订阅具有 ID user-2
的组:group-2
onGroupMessageCreated(userId : "
user-2
", groupId: :"group-2
"){...}
AWS AppSync 运行订阅解析器,它会生成订阅和失效过滤器。对于客户端 B,订阅筛选条件仅允许将数据发送到
,并为 group-2
和 user-2
定义了失效筛选条件。group-2
接下来,假设使用变更请求创建 ID 为
的新组消息,如以下示例中所示:message-1
createGroupMessage(id: "
message-1
", groupId : "group-1
", message: "test message"){...}
与定义的过滤器匹配的订阅客户端会自动通过 WebSockets以下方式接收以下数据有效负载:
{ "data": { "onGroupMessageCreated": { "id": "message-1", "groupId": "group-1", "message": "test message", } } }
客户端 A 收到该消息,因为筛选条件与定义的订阅筛选条件匹配。不过,客户端 B 不会收到该消息,因为该用户不属于
。此外,请求与订阅解析器中定义的订阅筛选条件不匹配。group-1
最后,假设使用以下变更请求从
中删除了 group-1
:user-1
removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}
该突变会启动订阅失效,如其extensions.invalidateSubscriptions()
解析器响应处理程序代码中所定义。 AWS AppSync 然后取消订阅客户端 A 并关闭其连接。 WebSocket 客户端 B 不受影响,因为变更中定义的失效负载与其用户或组不匹配。
当连接 AWS AppSync 失效时,客户端会收到一条消息,确认他们已取消订阅:
{ "message": "Subscription complete." }
在订阅失效筛选条件中使用上下文变量
与增强订阅筛选条件一样,您可以在订阅失效筛选条件扩展中使用 context
变量以访问某些数据。
例如,可以在变更中将电子邮件地址配置为失效负载,然后将其与通过 Amazon Cognito 用户池或 OpenID Connect 授权的订阅用户的电子邮件属性或声明进行匹配。失效筛选条件(在 extensions.setSubscriptionInvalidationFilter()
订阅失效器中定义)检查变更的 extensions.invalidateSubscriptions()
负载设置的电子邮件地址是否与从用户 JWT 令牌的 context.identity.claims.email
中检索的电子邮件地址匹配,从而启动失效。