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

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

取消订阅数 WebSocket 使用筛选器连接

InAmazon 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对象用于取消订阅中定义的订阅subscriptionField. 失效筛选条件也在onGroupMessageCreated订阅的响应映射模板。

如果$extensions.invalidateSubscriptions()payload 包含一个 ID,该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)

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

适用于示例,假设客户端 A 使用 ID 为新用户订阅user-1到带有 ID 的群组group-1使用以下订阅请求:

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

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

现在假设客户端 B 使用 ID 为用户订阅user-2到一个带有 ID 的群组group-2使用以下订阅请求:

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

Amazon AppSync运行订阅解析器,生成订阅和失效过滤器。对于客户端 B,订阅筛选器仅允许将数据发送到group-2,并且为两者都定义了失效过滤器user-2group-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. 此外,该请求与订阅解析器中定义的订阅筛选条件不匹配。

最后,假设user-1已从group-1使用以下更改请求:

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

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

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

{ "message": "Subscription complete." }

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

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

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