该页面翻译自 Google Chrome Extensions 与 Google Chrome Apps。除非特别说明,该页面的内容遵循 Creative Commons Attribution 3.0 License,代码示例遵循 BSD License。
Google Cloud Messaging for Chrome(GCM,用于 Chrome 浏览器的 Google 云消息服务)是为已登录的 Chrome 用户提供的一项服务,帮助开发者从服务器将消息数据发送至他们的 Chrome 应用与扩展程序,该服务是为了唤醒应用或扩展程序和/或提醒用户。例如,即使日历应用没有打开,日历更新也可以推送给用户。
该文档描述了设置和使用 GCM 的方法。如果您想了解更多内容,请阅读 pushMessaging Chrome API 以及 GCM 服务。如果需要帮助或者向我们提供反馈,请参见反馈。
粗略地看,推送消息以如下方式工作:
再深入一点来看,Chrome 网上应用店为您新发布的应用或扩展程序指派一个唯一的应用标识符。当用户安装您的应用或扩展程序时,客户端需要调用 pushMessaging.getChannelId。消息推送服务为客户端返回通道标识符,该标识符专门链接到您的应用程序标识符以及用户。无论您的客户端用什么方法向服务器发送通道标识符,都必须确保安全(例如使用 https)。例如,客户端可以向您服务器上的 RESTful API 发送一个 XHR 请求。
只要 Chrome 浏览器在后台或前台运行,即使扩展程序或应用还没有运行,它都会被唤醒以便传递消息。为了实现这一点,您的应用或扩展程序必须注册一个处理函数接收事件,就像为 launch 事件注册一样。
您的应用/扩展程序服务器负责向该服务发送推送消息。在所有推送消息请求中,您的服务器必须包含用户的通道标识符以及有效的 OAuth 2.0 访问令牌:访问令牌认证对服务的使用,通道标识符标志接收消息的用户和应用程序。
发送的所有新消息都会传递给以该用户的身份登录的 Chrome 用户配置文件下正在运行的该应用的所有实例,对于目前未连接到消息推送服务的 Chrome 浏览器实例,每一个子通道上发送的最新消息会放入队列以便之后传递。如果在 Chrome 浏览器未连接时发送了多个消息,Chrome 浏览器重新连接时可能只会收到发送的最后一条消息。
子通道也可以用来实现优先级架构。例如,如果您有一个即时通信应用程序,通话或视频聊天的请求可以直接通过,而不用等待所有保存的聊天消息清除。
如下是您使用消息推送服务时需要做的事情的简明清单(该文档的剩余部分详细介绍所有步骤):
getChannelId
。
onMessage
事件。
完成下列步骤就能创建客户端标识符:
https://developers.google.com/oauthplayground
。这一步中的客户端标识符以及客户端密钥将会在接下来的步骤中使用,确保将客户端标识符与密钥保存在安全的地方,不要将它们暴露给外界。
您需要两种 OAuth 2.0 令牌认证消息推送服务的每一个调用:刷新令牌与访问令牌。访问令牌为该服务的每一个调用认证,然而该令牌大约在一小时后过期。刷新令牌用来在一段时间内“刷新”访问令牌。这些令牌仅限于代表您的应用程序或扩展程序发送消息,而不能做任何其他事情。
要获取刷新令牌以及初始的访问令牌:
https://www.googleapis.com/auth/gcm_for_chrome
,并单击“Authorize APIs”按钮。刷新令牌永远不会过期,除非您显式地撤销访问权限。您需要记录并将刷新令牌嵌入到应用或扩展程序的服务端。
小心:刷新令牌不应该向您所在组织以外的任何人显示,永远不应该在客户端暴露。如果有人获得了您的刷新令牌,他们可能可以以您的服务器的身份发送消息。
要使用消息推送服务,您必须在 manifest.json
中声明
pushMessaging
权限:
"permissions": [ "pushMessaging", ]
与电子邮件地址类似,通道标识符用来标志您的应用或扩展程序的某个用户并向他们发送消息。您的应用或扩展程序需要将这一值发送给应用程序服务器,以便让服务器触发推送消息。要获取用户的通道标识符,请调用 pushMessaging.getChannelId,它使用回调函数向您的应用或扩展程序返回通道标识符:
chrome.pushMessaging.getChannelId(boolean interactive, function ChannelIdCallback)
当 interactive
标志设为 true
时,如果用户还没有登录则要求登录,并显示类似于这样的警告对话框:“您必须登录
Chrome 才能使用日历扩展程序接收推送消息。是否现在登录?”。
要为您的用户提供更好的体验,您的应用或扩展程序第一次调用
getChannelId
时 interactive 标志应该设为
false,否则用户会在启动您的应用或扩展程序之前就看到一个没有上下文的登录对话框。如果由于用户未登录,第一次调用失败,则可以再次调用
getChannelId
,并将该标志设为
true。进行第二次调用前,您应该提供一个上下文对话框。
每当 Chrome
浏览器接收到应用/扩展程序的推送消息时,它会将推送消息传递给应用或扩展程序的客户端。您的应用或扩展程序必须在每次启动时注册一个处理函数,接收该事件,就像为
launch 事件注册一样。这些应该添加到 background.js
中,例如:
function setupPush() { chrome.pushMessaging.onMessage.addListener(messageCallback); }
当消息到达时,应用或扩展程序不一定正在运行,处理函数可以在消息到达后注册。
要使用消息推送服务,您必须在 Chrome 网上应用店发布您的应用。
您需要一个有效的访问令牌才能向您的应用或扩展程序推送消息。要获取新的访问令牌,发送一个
HTTPS POST
请求,包含您的客户端标识符以及刷新令牌,在 Web
服务器应用程序中使用 OAuth 2.0
中更详细地描述了这一过程。示例请求如下所示:
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded client_id=291796959215.apps.googleusercontent.com& client_secret=0bKUtXN6ykk7Mj1lQxoBZ2mh& refresh_token=1%wMfyZvGcCxMSNEX4iTRdE0H1_Yt0wvImBz_iCuXF-UM& grant_type=refresh_token
这一请求的响应如下所示:
{ "access_token":"1/fFBGRNJru1FQd44AzqT3Zg", "expires_in":3920, "token_type":"Bearer" }
提醒:您应该缓存访问令牌以便使用,直到它过期。您请求访问令牌的频率是有限制的,如果您每次发送推送消息时都获取一个新的访问令牌,可能会被锁定一段时间而无法发送消息。
发送一个 POST
请求,包含通道标识符、子通道标识符以及消息内容至 API 端点
https://www.googleapis.com/gcm_for_chrome/v1/messages
。如下是一个示例
HTTP 调用:
POST /gcm_for_chrome/v1/messages Host: www.googleapis.com Content-Type: application/json Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg { 'channelId': '08144192009958038014/aaaaaaaaaabbbbbbbbbbcccccccccc', 'subchannelId': '0', 'payload': 'Thanks for installing my app!' }
消息可能会被合并。例如,如果您在子通道 1 上发送了多个消息,您可能只会看到最后一个消息及其内容。此外,内容有时候也可能被丢弃,将内容视为一项优化。您随时都可以返回服务器获取之前消息的内容,如果内容不存在的话获取数据。
如下是一个简单的例子,演示了一个推送消息,当它到达时显示文字通知:
function showPushMessage(message) { var notification = window.webkitNotifications.createNotification( '', '新消息', message.payload + " [" + message.subchannelId + "]"); notification.show(); }
您需要在 manifest.json
中添加 "notifications"
权限才能使用文字通知(参见桌面通知):
"permissions": [ "pushMessaging", "notifications" ]
推送消息的错误码指示推送请求是否被接受或拒绝。拒绝的原因包括发送者错误(例如格式错误的消息)、权限错误(例如已撤销的推送消息令牌)及操作性错误(例如消息推送服务目前不可用)。
如下是推送消息错误的简要概括:
要想在本地测试消息推送:
要测试工作在云端的推送消息,您必须首先确保您测试的应用或扩展程序通过所有者检查。推送消息服务器会检查调用 pushMessaging API 的应用或扩展程序的标识符是否匹配 Chrome 网上应用店中的应用或扩展程序标识符。这一所有者检查是为了防止他人未经您的同意就向您的应用或扩展程序发送消息。如果您的应用或扩展程序尝试使用 pushMessaging API,但是所有者检查失败了,它会收到 HTTP 状态码 500(内部服务器错误)。
所有者检查失败的一种常见情况是您正在开发一个应用,您没有将它上传并重新从
Chrome 网上应用店上下载下来运行。在这种情况下,您的应用的 manifest.json
文件中可能没有 key 字段。key
字段为应用指定了它的 Chrome 网上应用店标识符(一个包含 32
个字母的代码,例如“bafimiidcfafikaonocgmmcpbbhfjjik”)。如果您运行的应用没有
key,应用会使用随机生成的标识符,不会和 Chrome 网上应用店中的应用标识符匹配。例如,如果您从 original_app_dir 目录将您的应用上传至 Chrome
网上应用店,然后下载应用并解压缩至
downloaded_app_dir,然后以未打包扩展程序的方式从 original_app_dir
运行完全相同的应用,original_app_dir 中应用的 manifest.json 文件不会包含已下载的 key,应用的标识符也和已下载应用不同。
要想在云端测试推送消息:
https://chrome.google.com/extensions/detail/aaaaaaaaaabbbbbbbbbbcccccccccc?hl=en
包含标识符 aaaaaaaaaabbbbbbbbbbcccccccccc
。
Default/Extensions/<ID>/<versionString>/manifest.json
文件中寻找。
每一次您重新加载您的扩展程序用于测试时,您都需要确保 key 存在。然而每当您希望更新 Chrome 网上应用店中的已发布版本时,您需要移除 key,因为应用店不允许包含 key 的清单文件。
您可以通过 GCM for Chrome feedback Google 网上论坛提供关于 Google 云消息以及 pushMessaging API 的反馈,使用该群组寻求帮助、报告问题或请求新特性。