Google Cloud Messaging(GCM)简介与基本使用

Google Cloud Messaging(GCM)简介与基本使用

官方文档参考:https://developers.google.com/cloud-messaging/gcm

GCM简介

Google Cloud Messaging (GCM)是Google提供的服务器与终端进行消息传递的轻量级解决方案,支持客户端与服务器的双向传递,可实现push下发、即时通讯等功能。

GCM使用HTTP或XMPP协议,两种协议支持的消息最大容量都是4kb(ios为2kb)

消息格式支持JSON或者TEXT(文本)

支持的终端有iOS、Android、Chrome

基本框架:

 

角色:

1. GCM Connection Servers:google服务,在AppServer与客户端之间进行消息中转处理

2. Client App:客户端

3. App Server:自实现的服务器, 实现HTTP或XMPP协议, 通过GCM将消息发送给客户端

基本工作方式:

1. 客户端注册, 获得registration tokens。

2. 发送下行(downstream)消息:

App Server发送一个下行消息GCM,如果客户端处于离线状态,则GCM将消息放入    队列。上线后再发出。客户端收到消息进行处理。

3. 发送上行(upstream)消息--只在使用XMPP协议时支持:

a)         客户端发送一个上行消息给XMPP连接服务器, 如果App server离线,则将消息放入队列,当App Server上线后再发送。

b)        AppServer从XMPP连接服务器收取消息,并做以下事情

i.          分析消息头部(header)确认客户端发送的信息

ii.        发送“ack”给XMPP服务器,对其进行签收回应

iii.      对消息进行处理

GCM支持服务端的消息分发形式有

定向发送:服务器发送给指定的一个客户端

指定设备组(Device Groups)发送:服务器发送一个消息给一组指定客户端

Topic形式:客户端注册一个topic, GCM向这个topic发送消息, 所有注册了这个topic的客户端都会收到这个消息

Demo体验:

https://developers.google.com/cloud-messaging/android/start

可以按以上页面运行demo,对gcm有个直观感受

GCM服务端

一、GCM服务端包含两部分:

GCM Connection Servers由Google提供,支持Http或XMPP(一般用来实现即时通讯)协议

App Server由开发者实现,使用Http或XMPP与GCM Connection Servers通信,通过GCM提供的API对GCM Connection Servers进行调用

一般App Server需要提供以下能力:

A) 能够与客户端程序(client app)通信

B) 能够使用HTTP或XMPP协议向GCM Server发送消息

C) 能够使用Exponential Backoff处理request和response信息

D) 能够存储api key和客户端的token(不要将api key存储在客户端)

E) 如果使用XMPP,还要能够针对每个message生成一个唯一的id

二、两种协议:

HTTP:

1.只支持下行通信,即服务端发送消息给客户端。

2.同步性:App Server发送一个请求request,然后等待response返回,这个过程同步,在response没有返回之前整个过程是阻塞的。

3.JSON和文本消息都使用HTTP POST方法发送

XMPP:

1. 支持下行和上行通信,可以服务端向客户端发送消息,也可以客户端向服务端发送消息

2. 异步性:App Sever与客户端的交互过程是异步的,The XMPP connection server会异步地发送ack、json或者失败等消息

3. 不支持文本消息,JSON将被封装在XMPP消息体中

HTTP说明:

使用HTTP协议向GCM HTTP connection Server发送消息,必须通过POST方法。整个请求包含以下部分:

1. gcm地址

https://gcm-http.googleapis.com/gcm/send

2. 消息必须包含两部分:header和body

Header由Authorization和Content-Type组成

Authorization: key=YOUR_API_KEY

Content-Type: 指定消息体body的类型,如果使用json,则为application/json, 如果使用文本,则为application/x-www-form-urlencoded;charset=UTF-8。如果没有指定,则默认为文本

Body为消息内容,参数要符合GCM的api规范,api说明见HTTP Connection Server Reference

例如:

发送一个通知(notification)类型的消息

{ "notification": {
    "title": "Portugal vs. Denmark",
    "text": "5 to 1"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

上面的to参数指定的是客户端的token,及发送给指定设备

发送一个data类型的消息:

{ "data": {

    "score": "5x1",

    "time": "15:10"

  },

  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."

}

参数有必选和可选两种,像to参数就是必选的。

一个文本类型的消息是这样的:

collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.score=4x8&data.time=15:16.2342

下面模拟App Server,使用HTTP向GCM发送一个请求:

curl --header "Authorization: key=your_api_key" --header Content-Type:"application/json" https://gcm-http.googleapis.com/gcm/send -d "{\"notification\": {\"title\": \"Portugal vs Denmark\",\"text\": \"5 to 1\"},\"to\" : \"APA91bEcHbQrd3uGkAcZYV4iT8NsfCuMissVZRZ_OXAXZixbUIn7KhIWayjxkb02x4r7Dh4VU54Nvt1v7mAEV69rx6BTTE6oCBKVgN29Y8oVYc9RltV8mtxK77I5ivhs417Fwf4SVkxJ\"}"

XMPP说明:

参照以下教程

https://developers.google.com/cloud-messaging/ccs

三、三种消息分发方式:

To参数指定消息发送对象,有三种类型

1. 定向发送:

直接填写客户端token,如:

"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."

2. Topic广播:所有注册了指定topic的客户端都会收到,如:

"to" : "/topics/global"

这个值是自定义的, 需要客户端主动注册

3. 设备组:发送给一组设备,最大数量为20,一般用于一个用户用于多个设备的情况

用设备组,首先要获取要加入设备组的客户端的token,然后向GCM申请创建notification key, 所有设备共享同一个notification key

例如:

https://android.googleapis.com/gcm/notification
Content-Type:application/json
Authorization:key=API_KEY
project_id:SENDER_ID
{
   "operation": "create",
   "notification_key_name": "appUser-Chris",
   "registration_ids": ["4", "8", "15", "16", "23", "42"]
}

创建成功后,可以发送消息:

https://gcm-http.googleapis.com/gcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
  "to": "aUniqueKey",
  "data": {
    "hello": "This is a GCM Device Group Message!",
   }
}

GCM客户端实现(Android

建议在Android Studio下开发, 本文as版本为1.4

环境要求:

1. 在2.3以上系统,并且装有Google Play Service

2. GCM直接使用Google Play Service的现有连接,3.0以前的系统需要使用帐号登录, 4.0.4以后不需要

实现步骤:

1. 创建一个新的应用

2. 获取配置文件

进入以下地址,创建一个应用,填写应用名与包名(与刚刚创建的应用一致),得到Server API Key和Sender ID

https://developers.google.com/mobile/add?platform=android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com%2Fcloud-messaging%2Fandroid%2Fclient&cntlbl=Continue%20Adding%20GCM%20Support&%3Fconfigured%3Dtrue

点击Generate configuration files, 下载配置文件

 

将加载的google-services.json文件放到android工程下的module根目录下,如app/

3. 在gradle中配置google play service

a)         在工程级的gradle的dependencies中加入classpath

 

b)        在module级的gradle的dependencies中加入:

 

注意,这里的版本要和你本地的android sdk内的gcm版本一致,gcm sdk在这里:

[AndroidSDK]\extras\google\m2repository\com\google\android\gms\play-services-gcm

c)         在module级的gradle中声明plugin

 

4. 编辑menifest

a) 声明一个<application-package-name> + ".permission.C2D_MESSAGE"格式的permission, 防止其他应用接受和发送你的消息,如

<permission android:name="com.joy.gcmtest.permission.C2D_MESSAGE"
     android:protectionLevel="signature" />
 <uses-permission android:name="com.joy.gcmtest.permission.C2D_MESSAGE" />

这个permission的格式必须固定, 否则无效

b) 声明一个GcmReceiver, 用来处理GCM给应用发送的消息, 使用时需要声明一下权限

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

这个GcmReciever不需要自定义, 直接声明在menifest里即可

<receiver
     android:name="com.google.android.gms.gcm.GcmReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND" >
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="com.example.gcm" />
     </intent-filter>
 </receiver>

c) 声明一个GcmListenerService, 并进行自定义实现,如下

<service
     android:name="com.joy.gcmtest.MyGcmListenerService"
     android:exported="false" >
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
     </intent-filter>
 </service>

MyGcmListenerService是一个GcmListenerService的实现

 

这个Service用来处理从GCM收到的消息,当GCM发送过来消息, 会调用onMessageReceived方法, 这个方法中,data参数存储了消息内容

  d) 声明一个InstanceIDListenerService的实例

<service
     android:name="com.joy.gcmtest.MyInstanceIDListenerService"
     android:exported="false">
     <intent-filter>
         <action android:name="com.google.android.gms.iid.InstanceID" />
     </intent-filter>
 </service>

MyInstanceIDListenerService是InstanceIDListenerService的自定义实现,用来处理registration tokens的创建、更新等

  e) 如果想在设备睡眠情况下, 收到消息时将其唤醒, 可添加android.permission.WAKE_LOCK权限

4. Java代码

a)         应用启动时, 首先检查googleplay是否可用

 

b)        注册token

InstanceID instanceID = InstanceID.getInstance(this);
 String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
         GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

getToken()的参数为senderId, 如果使用R.string.gcm_defaultSenderId,则是从本地的google-services.json文件里取出之前申请的senderId。

注册token后, 如果token发生变化, 会调用MyInstanceIDListenerService的onTokenRefresh()方法, 这时需要重新获取token

获得token后, 可以将此token发送给app server保存起来

每个android客户端应用的实例都有一个唯一的token,同一台机器重复卸载安装两次应用,他们的token是不一样的

c)  订阅topic

如果支持topic方式发送, 需要订阅topic

private void subscribeTopics(String token) throws IOException {
     GcmPubSub pubSub = GcmPubSub.getInstance(this);
     for (String topic : TOPICS) {
         pubSub.subscribe(token, "/topics/" + topic, null);
     }
 }

d)  模拟App Server向GCM发送一个消息,GCM会将消息发送给客户端

$ curl --header "Authorization: key=your_api_key --header Content-Type:"application/json" https://gcm-http.googleapis.com/gcm/send -d "{\"to\":\"/topics/global\", \"data\":{\"message\":\"This is a Joy Custom GCM Topic TEST Message\"}}"

随后,GCM会调用客户端MyGcmListenerService的onMessageReceived方法,由此客户端就能收到消息了。

 以上客户端代码可参考官方demo GitHub - googlesamples/google-services: A collection of quickstart samples demonstrating the Google APIs for Android and iOS

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值