Amazon Simple Notification Service
开发人员指南 (API Version 2010-03-31)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

发送 Amazon SNS 消息至 HTTP/HTTPS 终端节点

您可以使用 Amazon SNS 向一个或多个 HTTP 或 HTTPS 终端节点发送通知消息。为终端节点订阅主题时,您可以向主题发布通知,Amazon SNS 将发送 HTTP POST 请求,向已订阅终端节点传递通知内容。订阅终端节点时,您可以选择 Amazon SNS 是否使用 HTTP 或 HTTPS 向终端节点发送 POST 请求。如果您使用 HTTPS,则可以利用 Amazon SNS 对以下功能的支持:

  • 基本和摘要式访问身份验证 – 这使您可以在 HTTPS URL 中为 HTTP POST 请求指定用户名和密码,如 https://user:password@domain.com 或 https://user@domain.com。在使用 HTTPS 建立的 SSL 连接上,会对用户名和密码进行加密。只有域名以明文形式发送。有关基本和摘要式访问身份验证的更多信息,请参阅 http://www.rfc-editor.org/info/rfc2617

此项请求包含已向主题发布的相关主题和消息,包括 JSON 文档中通知的元数据。此项请求与以下 HTTP POST 请求相似。有关 HTTP 标头和请求正文 JSON 格式的详细信息,请参阅 HTTP/HTTPS 标题HTTP/HTTPS 通知 JSON 格式

Copy
POST / HTTP/1.1 x-amz-sns-message-type: Notification x-amz-sns-message-id: da41e39f-ea4d-435a-b922-c6aae3915ebe 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:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55 Content-Length: 761 Content-Type: text/plain; charset=UTF-8 Host: ec2-50-17-44-49.compute-1.amazonaws.com Connection: Keep-Alive User-Agent: Amazon Simple Notification Service Agent { "Type" : "Notification", "MessageId" : "da41e39f-ea4d-435a-b922-c6aae3915ebe", "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic", "Subject" : "test", "Message" : "test message", "Timestamp" : "2012-04-25T21:49:25.719Z", "SignatureVersion" : "1", "Signature" : "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=", "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:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55" }

按照下面步骤启用 Amazon SNS 主题向 HTTP 或 HTTPS 终端节点发送消息:

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

步骤 2:订阅 Amazon SNS 主题 HTTP/HTTPS 终端节点

步骤 3:确认订阅

步骤 4:设置订阅发送重试策略(可选)

步骤 5:授予用户发布主题的权限(可选)

步骤 6:向 HTTP/HTTPS 终端节点发送消息

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

确保供 Amazon SNS 使用发送订阅确认和通知消息的 HTTP 或 HTTPS 终端节点能够处理 HTTP POST 请求之后,方可订阅相关主题的 HTTP 或 HTTP 终端节点。一般情况下,这要求创建和部署 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 请求为订阅确认消息的一个示例。

    Copy
    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" : "2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736", "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=2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736", "Timestamp" : "2012-04-26T20:45:04.751Z", "SignatureVersion" : "1", "Signature" : "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=", "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem" }
  2. 您的代码将分析 HTTP POST 请求正文中的 JSON 文档,读取构成 Amazon SNS 消息的名称/值对。使用 JSON 分析器将控制字符的转义字符转换回 ASCII 字符值(例如,将 \n 转换成换行符)。您可以使用现有 JSON 分析器,例如 Jackson JSON 处理器(http://wiki.fasterxml.com/JacksonHome) 或者由您自己写入。要将主题和消息字段中的文本作为有效 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。

    Copy
    <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 操作,并将 SubscriptionConfirmation 消息中的 Token 设定为令牌值,亦可以完成订阅的确认操作。如果您仅允许主题所有者和订阅所有者拥有取消订阅终端节点的权限,那么您可以通过 AWS 签名调用 ConfirmSubscription 操作。

    通知

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

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

    Copy
    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" : "EXAMPLEw6JRNwm1LFQL4ICB0bnXrdB8ClRMTQFGBqwLpGbM78tJ4etTwC5zU7O3tS6tGpey3ejedNdOJ+1fkIp9F2/LmNVKb5aFlYq+9rk9ZiPph5YlLmWsDcyC5T+Sy9/umic5S0UQc2PEtgdpVBahwNOdMW4JPwk0kAJJztnc=", "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 标头字段确定消息。通过对比您已处理收件的消息 ID,您可以确定该消息是否经过重新发送。

  7. 如果您正在订阅 HTTPS 终端节点,那么请确保您的终端节点具备由可信赖证书颁发机构 (CA) 颁发的服务器证书。Amazon SNS 仅向符合以下条件的 HTTPS 终端节点发送消息,即该终端节点应具备受 Amazon SNS 信赖的 CA 签署的服务器证书。有关可信 CA 清单,请参阅 已由 Amazon SNS 认可的 HTTPS 终端节点证书颁发机构 (CA)

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

步骤 2:订阅 Amazon SNS 主题 HTTP/HTTPS 终端节点

必须为终端节点订阅 Amazon SNS 主题,方能通过主题向 HTTP 或 HTTPS 终端节点发送消息。您可以通过终端节点的 URL 指定终端节点。您可以利用 Amazon SNS 控制台、sns-subscribe 命令或 Subscribe API 操作来订阅主题。开始操作前,应确保拥有想要订阅终端节点的 URL,并且该终端节点按照步骤 1 所述已准备好接收确认和通知消息。

利用 Amazon SNS 控制台为 HTTP 或 HTTPS 终端节点订阅主题

  1. 通过以下网址登录 AWS 管理控制台 并打开 Amazon SNS 控制台:https://console.amazonaws.cn/sns/v2/home

  2. 在左侧导航窗格中,单击 Topics,然后选择主题。

  3. 单击 Other actions 下拉列表,然后选择 Subscribe to topic

  4. Protocol 下拉列表中,选择 HTTPHTTPS

  5. Endpoint 框中,粘贴您想要主题将消息发送至的终端节点的 URL,然后单击 Create subscription

  6. 对于“Subscription request received!”(订阅请求已接收!)消息,单击 “Close”。

    您新建订阅的 订阅 ID 将显示 PendingConfirmation。当您确认订阅时,Subscription ID (订阅 ID) 将显示订阅 ID。

步骤 3:确认订阅

当您完成终端节点的订阅后,Amazon SNS 会向该终端节点发送一条订阅确认消息。您已将可执行 步骤 1 所述操作的代码部署到您的终端节点上。尤其是,终端节点的代码必须检索来自订阅确认消息的 SubscribeURL值,并访问 SubscribeURL自身指定的位置或让其对您可用,这样您就可以手动访问 SubscribeURL,例如,利用 Web 浏览器。在订阅确认前,Amazon SNS 不会向终端节点发送消息。当您访问 SubscribeURL时,该响应将包括 XML 文档,该文档包含指定订阅 ARN 的元素 SubscriptionArn。您也可以利用 Amazon SNS 控制台验证是否已确认订阅:订阅 ID 将显示订阅 ARN,而非您首次添加订阅时看到的 PendingConfirmation值。

步骤 4:设置订阅发送重试策略(可选)

默认情况下,如果消息初次发送失败,那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。按照步骤 1 所述,您的终端节点应包括能够处理已重试消息的代码。通过设置主题或订阅的发送策略,您可以控制 Amazon SNS 即将重试失败消息的频率和间隔。您可以设置主题或特定订阅的发送策略。

步骤 5:授予用户发布主题的权限(可选)

默认情况下,只有主题所有者才拥有发布主题的权限。您应利用 AWS Identity and Access Management (IAM) 授予发布主题的权限,启用其他用户或应用程序发布主题。有关向 IAM 用户授予 Amazon SNS 操作权限的更多信息,请参阅控制用户访问您的 AWS 账户

可以采取两种方式控制对主题的访问:

  • 添加策略至 IAM 用户或群组。向用户授予主题权限的最简单方式就是创建群组,向该群组添加适当策略,再向此群组添加用户。相比较而言,向群组添加或删除用户,比追踪您为单独用户而设定的各项策略要简单得多。

  • 添加策略至主题。如果您想向另一 AWS 账户授予主题权限,那么唯一的方法是添加策略,并且该策略必须具备您想向其授予权限的主要 AWS 账户。

绝大多数情况下,您应使用第一种方法(通过向群组添加或删除适当用户的方式,向群组添加策略,管理用户权限)。如果您需要向另一账户的用户授予权限,请使用第二种方法。

如果您已将以下策略添加至 IAM 用户或群组,那么您应向该组用户或成员授予权限,允许上述用户或成员对主题 MyTopic 执行 sns:Publish 操作。

Copy
{ "Version":"2012-10-17", "Statement":[{ "Sid":"AllowPublishToMyTopic", "Effect":"Allow", "Action":"sns:Publish", "Resource":"arn:aws:sns:us-east-1:123456789012:MyTopic" } ] }

以下策略示例显示如何向主题授予另一账户权限。

注意

当您允许另一 AWS 账户访问您账户中的资源时,您也就向拥有管理员级访问(通配符访问)的 IAM 用户授予访问该资源的权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您要向该 AWS 账户中的特定 IAM 用户授予访问您资源的权限,那么拥有管理员级访问的账户或 IAM 用户必须将此项资源访问权限委派给上述特定 IAM 用户。有关跨账户委派的更多信息,请参阅 使用 IAM 指南 中的 启用跨账户访问

如果您向账户 123456789012 的主题 MyTopic 添加以下策略,那么您同时也是向账户 111122223333 授予在此主题上执行 sns:Publish 操作的权限。

Copy
{ "Version":"2012-10-17", "Id":"MyTopicPolicy", "Statement":[{ "Sid":"Allow-publish-to-topic", "Effect":"Allow", "Principal":{ "AWS":"111122223333" }, "Action":"sns:Publish", "Resource":"arn:aws:sns:us-east-1:123456789012:MyTopic" } ] }

步骤 6:向 HTTP/HTTPS 终端节点发送消息

您可以通过发布主题的方式,向主题订阅发送消息。您可以利用 Amazon SNS 控制台、sns-publish 命令或 发布API 来发布主题。

如果您遵循 步骤 1,那么在您的终端节点部署的代码将对通知进行处理。

利用 Amazon SNS 控制台发布主题

  1. 利用拥有发布主题权限的 AWS 账户或 IAM 用户具备的凭证,登录 AWS 管理控制台 并通过 https://console.amazonaws.cn/sns/ 打开 Amazon SNS 控制台。

  2. 在左侧导航窗格中,单击 Topics,然后选择一个主题。

  3. 单击 Publish to topic 按钮。

  4. Subject 框中,输入一个主题(例如 Testing publish to my endpoint)。

  5. Message 框中,输入一些文本(例如 Hello world!),然后单击 Publish message

    界面将显示如下消息:“Your message has been successfully published”(您的消息已成功发布)。