使用过滤器取消订阅 WebSocket 连接 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用过滤器取消订阅 WebSocket 连接

在中Amazon AppSync,您可以根据特定的筛选逻辑强制取消订阅并关闭(使 WebSocket 连接的客户端失效)连接。这在与授权相关的场景中很有用,例如当您从群组中移除用户时。

订阅失效是对突变中定义的有效负载的响应。我们建议您将用于使订阅连接失效的突变视为 API 中的管理操作,并通过将权限限制为管理员用户、群组或后端服务来相应地确定权限范围。例如,使用架构授权指令,例如@aws_auth(cognito_groups: ["Administrators"])@aws_iam。有关更多信息,请参阅 使用其他授权模式

失效过滤器使用与增强型订阅筛选器相同的语法和逻辑。使用以下方法定义这些筛选条件:

  • $extensions.invalidateSubscriptions()— 在 GraphQL 解析器的突变响应映射模板中定义。

  • $extensions.setSubscriptionInvalidationFilter()— 在 GraphQL 解析器的响应映射模板中定义的与变异相关的订阅。

有关失效筛选扩展的更多信息,请参阅解析器映射模板实用程序参考

使用订阅失效

要查看订阅失效的工作原理Amazon 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"]) } schema { mutation: Mutation subscription: Subscription }

removeUserFromGroup突变响应映射模板中定义失效过滤器,如下所示:

## Response Mapping Template - removeUserFromGroup mutation $extensions.invalidateSubscriptions({ "subscriptionField": "onGroupMessageCreated", "payload": { "userId": $ctx.args.userId, "groupId": $ctx.args.groupId } }) $util.toJson($context.result)

调用变异时,payload对象中定义的数据用于取消订阅中定义的订阅subscriptionFieldonGroupMessageCreated订阅的响应映射模板中还定义了失效过滤器。

如果$extensions.invalidateSubscriptions()负载包含的 ID 与筛选器中定义的来自已订阅客户端的 ID 相匹配,则相应的订阅将被取消订阅。此外, WebSocket 连接已关闭:

## Response Mapping Template - onGroupMessageCreated subscription $extensions.setSubscriptionFilter({ "filterGroup": [ { "filters" : [ { "fieldName" : "groupId", "operator" : "eq", "value" : $ctx.args.groupId } ] } ] }) $extensions.setSubscriptionInvalidationFilter({ "filterGroup": [ { "filters" : [ { "fieldName" : "userId", "operator" : "eq", "value" : $ctx.args.userId }, { "fieldName" : "groupId", "operator" : "eq", "value" : $ctx.args.groupId } ] ] }) $util.toJson($context.result)

请注意,订阅响应模板可以同时定义订阅筛选器和失效过滤器。

例如,假设客户端 Agroup-1 使用以下订阅请求将具有该 ID 的新用户订阅user-1到具有该 ID 的群组:

onGroupMessageCreated(userId : "user-1", groupId: :"group-1"){...}

Amazon AppSync运行订阅解析器,该解析器生成在前面的onGroupMessageCreated响应映射模板中定义的订阅和失效过滤器。对于客户端 A,订阅筛选器仅允许将数据发送到group-1,并且为user-1和定义了失效过滤器group-1

现在假设客户端 Bgroup-2 使用以下订阅请求将具有该 ID 的用户订阅user-2到具有该 ID 的群组:

onGroupMessageCreated(userId : "user-2", groupId: :"group-2"){...}

Amazon AppSync运行订阅解析器,该解析器生成订阅和失效过滤器。对于客户端 B,订阅筛选器仅允许将数据发送到group-2,并且为user-2和定义了失效过滤器group-2

接下来,假设使用变更请求创建了一条带有 IDmessage-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。此外,该请求与订阅解析器中定义的订阅过滤器不匹配。

最后,假设user-1group-1使用以下突变请求已将其删除:

removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}

该变异会启动其$extensions.invalidateSubscriptions()解析器响应映射模板方法中定义的订阅失效。 Amazon AppSync然后取消订阅客户端 A 并关闭其 WebSocket 连接。客户端 B 不受影响,因为突变中定义的失效负载与其用户或组不匹配。

当连接Amazon AppSync失效时,客户端会收到一条消息,确认他们已取消订阅:

{ "message": "Subscription complete." }

在订阅失效过滤器中使用上下文变量

与增强型订阅筛选器一样,您可以使用订阅失效过滤器扩展插件中的$context变量来访问某些数据。例如,由 Amazon DynamoDB 的GetItem操作检索到的属性,该属性定义于相同的订阅请求映射模板 ($context.result.severity)、用户身份 ($context.identity.claims.group) 或请求 () 的特定参数(如有必要$context.args.userId)中。

可以将电子邮件地址配置为变异中的失效有效负载,然后将其与电子邮件属性或已获得 Amazon Cognito 用户池或 OpenID Connect 授权的订阅用户的声明进行匹配。$extensions.setSubscriptionInvalidationFilter()订阅失效器中定义的失效过滤器检查变异$extensions.invalidateSubscriptions()负载设置的电子邮件地址是否与从用户的 JWT 令牌中检索到的电子邮件地址相匹配$context.identity.claims.email,从而启动失效。