步骤 1: 确保您的终端节点已准备好处理 Amazon SNS 消息 - Amazon Simple Notification Service
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

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

步骤 1: 确保您的终端节点已准备好处理 Amazon SNS 消息

确保供 Amazon SNS 使用发送订阅确认和通知消息的 HTTP 或 HTTPS 终端节点能够处理 HTTP POST 请求之后,方可订阅相关主题的 HTTP 或 HTTPS 终端节点。一般情况下,这要求创建和部署 Web 应用程序(例如,若您的终端主机正在通过 Apache 和 Tomcat 运行 Linux,则为 Java servlet),用于处理来自 Amazon SNS 的 HTTP 请求。当您订阅 HTTP 终端节点时,Amazon SNS 会向其发送一条订阅确认请求。当您创建订阅时,终端节点必须已经准备好接收和处理此请求,因为 Amazon SNS 会同时发送此请求。Amazon SNS 不会在确认订阅前向终端节点发送通知。订阅确认后,在已订阅主题上执行发布操作时,Amazon SNS 会向终端节点发送通知。

设置您的终端节点,处理订阅确认和通知消息

  1. 您的代码将读取 Amazon SNS 向您的终端节点发送的 HTTP POST 请求的 HTTP 标头。您的代码将查找标头字段 x-amz-sns-message-type,此标头字段将显示Amazon SNS向您发送的消息类型。查看标头后,您可以确定消息类型,而无需分析 HTTP 请求正文。您需要处理以下两种类型: SubscriptionConfirmationNotification。 仅当从主题中删除订阅时,才会使用 UnsubscribeConfirmation 消息。

    有关 HTTP 标头的详细信息,请参阅 HTTP/HTTPS 标题。以下 HTTP POST 请求为订阅确认消息的一个示例。

    POST / HTTP/1.1 x-amz-sns-message-type: SubscriptionConfirmation x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic Content-Length: 1336 Content-Type: text/plain; charset=UTF-8 Host: example.com Connection: Keep-Alive User-Agent: Amazon Simple Notification Service Agent { "Type" : "SubscriptionConfirmation", "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b", "Token" : "2336412f37f...", "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic", "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.", "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...", "Timestamp" : "2012-04-26T20:45:04.751Z", "SignatureVersion" : "1", "Signature" : "EXAMPLEpH+...", "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem" }
  2. 您的代码将分析 HTTP POST 请求正文中的 JSON 文档,以读取构成 Amazon SNS 消息的名称/值对。使用 JSON 分析器将控制字符的转义字符转换回 ASCII 字符值(例如,将 \n 转换成换行符)。您可以使用现有 JSON 分析器(例如 Jackson JSON 处理器)或者由您自己写入。要将主题和消息字段中的文本作为有效 JSON 发送,Amazon SNS 必须将部分控制字符转换成可包含在 JSON 文档中的转义字符。向您的终端节点发送的 POST 请求正文中包括 JSON 文档,当您接收到该文档时,若您想要获取发布到主题上的原始主题和消息的精确字符,则必须将转义字符转换回其原始字符值。由于签名采用了原始形式的消息和主题作为待签字符串的一部分,因此如果您想要验证通知签名,则上述操作非常重要。

  3. 您的代码应对 Amazon SNS 发送的通知、订阅确认或取消订阅确认消息进行验证。使用 Amazon SNS 消息所含信息,终端节点可以重新创建签名,以便您可以通过将自己的签名与 Amazon SNS 随消息发送的签名进行匹配,来验证消息的内容。有关验证消息签名的更多信息,请参阅 验证 Amazon SNS 消息签名

  4. 根据标头字段 x-amz-sns-message-type 指定的类型,您的代码将读取 HTTP 请求正文所含的 JSON 文档,并处理该消息。这里是处理两大主要消息类型的指导原则:

    SubscriptionConfirmation

    读取 SubscribeURL 值,访问此 URL。要确认订阅并通过此终端节点接收通知,必须访问 SubscribeURL URL(例如,向此 URL 发送 HTTP GET 请求)。参阅上一步中 HTTP 请求示例,查看 SubscribeURL 相关情况。有关 SubscriptionConfirmation 消息格式的更多信息,请参阅 HTTP/HTTPS 订阅确认 JSON 格式。访问 URL 时,您将获取与以下 XML 文档相似的响应。文档会在 ConfirmSubscriptionResult 元素内返回终端节点的订阅 ARN。

    <ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/"> <ConfirmSubscriptionResult> <SubscriptionArn>arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55</SubscriptionArn> </ConfirmSubscriptionResult> <ResponseMetadata> <RequestId>075ecce8-8dac-11e1-bf80-f781d96e9307</RequestId> </ResponseMetadata> </ConfirmSubscriptionResponse>

    作为访问 SubscribeURL 的替代方法,您可以使用 ConfirmSubscription 操作确认订阅,并将 Token 消息中的 SubscriptionConfirmation 设置为其对应值。如果您仅允许主题所有者和订阅所有者拥有取消订阅终端节点的权限,那么您可以通过 AWS 签名调用 ConfirmSubscription 操作。

    通知

    读取 SubjectMessage 值,获取已向主题发布的通知信息。

    有关 Notification 消息格式的详细信息,请参阅 HTTP/HTTPS 标题。以下 HTTP POST 请求为向终端节点 example.com.发送的通知消息的示例。

    POST / HTTP/1.1 x-amz-sns-message-type: Notification x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324 x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96 Content-Length: 773 Content-Type: text/plain; charset=UTF-8 Host: example.com Connection: Keep-Alive User-Agent: Amazon Simple Notification Service Agent { "Type" : "Notification", "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324", "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic", "Subject" : "My First Message", "Message" : "Hello world!", "Timestamp" : "2012-05-02T00:54:06.655Z", "SignatureVersion" : "1", "Signature" : "EXAMPLEw6JRN...", "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem", "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96" }
  5. 确保您的终端节点已通过适当的状态代码对来自 Amazon SNS 的 HTTP POST 消息作出响应。此项连接将在 15 秒内超时。在连接超时前,如果您的终端节点不响应,或者您的终端节点返回的状态代码超出 200–4xx 范围,那么 Amazon SNS 会认为消息发送尝试失败。

  6. 确保您的代码能够处理 Amazon SNS 的消息发送重试。如果 Amazon SNS 未能接收到从终端节点发出的发送成功响应,它将会尝试再次发送消息。这适用于包括订阅确认消息在内的所有消息。默认情况下,如果消息初次发送失败,那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。

    注意

    消息请求 15 秒后超时。这表示,如果因超时引起消息发送失败,那么 Amazon SNS 将在前一次发送尝试后 35 秒左右重新发送。您可以为终端节点设置不同的发送策略。

    为清晰起见,Amazon SNS 仅在传输 x-amz-sns-message-id 标头失败后重试。通过比较您已处理并传入消息的消息的 IDs,您可以确定消息是否为重试尝试。

  7. 如果您要订阅 HTTPS 终端节点,请确保终端节点具备由可信赖证书颁发机构 (CA) 颁发的服务器证书。Amazon SNS 将仅向具有 Amazon SNS 所信任 CA 签署的服务器证书的 HTTPS 终端节点发送消息。

  8. 对您已创建的代码进行部署,以便接收 Amazon SNS 消息。当您订阅终端节点时,该终端节点必须准备好至少接收订阅确认消息。