GCM là gì?

GCM hay còn gọi là Google Cloud Messageing, đây là một Service được Google phát triển giúp

android developer dễ dàng triển khai việc send message từ server tới mobile của bạn.

Server mà bạn develop có thể là Android, và cũng có thể là Browser. Các kiểu data có thể là các

message nhỏ hoặc các dữ liệu có dung lượng nhỏ hơn hoặc bằng 4kb. GCM xử lý dữ liệu theo kiểu

hàng đợi (queue) các message và chuyển tới các ứng dụng android dạng Push notification. GCM thay

thế cho phiên bản beta C2DM (Cloud to Device Messaging).

1. Các tính chất đặc trưng của GCM

  • Cho phép server của các ứng dụng phía thứ 3 (3rd-party) gửi message đến từng ứng dụng.

  • Phía ứng dụng không cần thiết phải chạy chức năng nhận tin nhắn liên tục. GCM sẽ đánh thức các

thiết bị và broadcast message.

  • không cung cấp các interface hay các thư viện xử lý thông tin mà đơn thuần chỉ gửi tin nhắn

đến thiết bị.

  • Android > 2.3 + Google Play Store or Emulator chạy bằng Google APIs.

  • Sử dụng kết nối cho Google Service hiện có. (đối với android version < 3 đòi hỏi phải có

google account).

2. Tổng quan kiến trúc GCM

Screenshot from 2016-02-29 15:21:42.png

  • Một GCM bao gồm một Google connection server, một app server bên trong môi trường ở đó tương

tác với server thông qua giao thức HTTP hoặc XMPP, và một app client là Android hoặc iOS,...

** Làm thế nào để các thành phần tương tác với nhau?**

  • Google GCM Connection Servers chấp nhận downstream message từ app server của bạn and gưỉ chúng

tới app client. Giao thức XMPP cũng có thể chấp nhận message được gửi lên từ client app và chuyển

tiếp chúng tới App server.

  • Trên App server của bạn, bạn áp dụng cho 2 phương thức HTTP hoặc XMPP để giao tiếp với GCM

Connection server. App server gửi downstream message tới GCM connection server, connection server

sẽ lưu trữ message trong hàng đợi và gửi chúng tới client app. Nếu bạn sử dụng XMPP giao thức thì

app server của bạn có thể nhận messages gửi từ client app.

  • Client App để nhận và gửi GCM message, ứng dụng này phải đăng ký với GCM và một định danh duy

nhất gọi là registration token.

3. Các thành phần của GCM

  • Components - Toàn bộ vai trò chính trong GCM

  • Credentials - Là IDs và token được sử dụng trong GCM để đảm bảo rằng tất cả các thành phần

được xác nhận, và tin nhắn được gửi đi chính xác.

3.1 Components

  • GCM Connection Servers: Google server liên quan đến việc gửi tin nhắn giữa app server và

client app.

  • Client app: Một GCM client app cho phép ứng dụng giao tiếp với App server.

  • App Server: Một App server để gửi dữ liệu tới App client thông qua GCM connection server. Nếu

app server sử dụng giao thức XMPP, nó cũng có thể nhận tin nhắn được gửi từ client apps.

3.2 Credentials

  • Sender ID: Số Project ID khi cấu hình project API của bạn. Số ID này đăng ký với app server để

cam kết rằng server sẽ gửi dữ liệu tới Client app.

  • API Key: Một API key được lưu trên App server để app server xác thực quyền truy cập tới Google

service. Trong HTTP, API key bao gồm trong phần Headed của phương thức POST được yêu cầu gửi tin

nhắn. Với XMPP, API key được bao gồm trong SASL PLAIN xác thực yêu cầu như mật khẩu để kết nối.

API key không được bao gồm trong client code.

  • Appication ID: Đây là ID của app client được đăng ký để nhận dữ liệu từ server.

3.3 Cách đăng ký Application ID

  • Android: sử dụng package name trong tệp tin manifest.

  • iOS: sử dụng app's bundle để xác định.

  • Chrome: sử dụng tên chrome extension.

  • Registration Token: Một token được đăng ký giữa client và server để cho phép client app nhận

tin nhắn. Việc đăng ký tokens phải là bí mật.

  • Vòng đời của GCM:

    • Đăng ký GCM: Client app đăng ký token với App server.

    • Client app kết nối với app server thông qua token đã đăng ký.

    • App server sẽ lưu token đã đăng ký từ client.

    • Gửi và nhận messages:

      • Gửi tin nhắn: App server gửi tin nhắn tới client app:

      • GCM connection server đưa tin nhắn vào hàng đợi và lưu tin nhắn nếu thiết bị offline.

      • Khi thiết bị online, GCM connection server gửi tin nhắn tới thiết bị.

      • Trên thiết bị, app client nhận tin nhắn tùy theo từng nền tảng đã đăng ký với app server.

      • Nhận tin nhắn: Client app nhận tin nhắn từ GCM connection server.

4. Cài đặt GCM Client App on Android

  • Google Cloud Messaging (GCM) Android là một app client chạy trên thiết bị Android. Để viết code

ứng dụng chúng ta sử dụng GoogleCloudMessaging API và Android Studio với Gradle.

Yêu cầu để chạy GCM Android client:

  • GCM yêu cầu thiết bị chạy Android 2.2 hoặc cao hơn và phải cài đặt ứng dụng Google Play

Store, hoặc thiết bị giả lập chạy Android 2.2 với Google APIs.

  • Nếu bạn muốn tiêp tục sử dụng các thuộc tính GCM được phân phát thông qua Google Play

Services, thiết bị phải chạy Android 2.3 hoặc cao hơn. Bạn cũng có thể sử dụng giả lập chạy

Android 2.3 trở lên với Google APIs.

  • Trên các thiết bị Android, GCM sử dụng connection tồn tại cho Google services. Với các thiết

bị chạy Android version dưới 3.0 thì phải cài đặt tài khoản google, với thiết bị chạy Android

version từ 4.0.4 trở lên thì không cần tài khoản google.

5. Cài đặt Google Service trong Android studio:

 dependencies {
      compile 'com.google.android.gms:play-services-gcm:8.1.0'
}
  • Trong tập tin Application's Manifest:

  • <application-package-name> + ".permission.C2D_MESSAGE" đăng ký quyền cho phép ứng dụng

nhận gửi và nhận tin nhắn từ GCM.

    <permission android:name="com.example.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="asia.geeeksplay.permission.C2D_MESSAGE" />
  • com.google.android.c2dm.permission.SEND cung cấp quyền nhận tin nhắn từ GCM.
        <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="asia.geeeksplay" />
            </intent-filter>
        </receiver>

-GcmListenerService xử lý các kiểu tin nhắn được gửi từ app server và hiển thị Notification

trên thiết bị.

         <service
            android:name=".service.GeeekGCMListenerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
  • InstanceIDListenerService thuộc tính này để xử lý như tạo, cập nhật của việc đăng ký tokens.
        <service
            android:name=".service.GeeekInstanceIDListenerService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID"/>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            </intent-filter>
        </service>
  • BIND_NETWORK_TASK_SERVICE: sử dụng bởi Google Play Services, cung cấp quyền bảo mật cho việc

gửi và nhận tin nhắn.

         <service android:name=".service.RegistrationGCMService"
            android:exported="true"
            android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE" >
            <intent-filter>
                <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
            </intent-filter>
        </service>
  • Để đăng ký Tokens ID với App server chúng ta sử dụng phương thức onTokenRefresh() như sau:

public class GeeekInstanceIDListenerService extends InstanceIDListenerService {

    private static final String TAG = "GeeekInstanceIDListenerService";

    @Override
    public void onTokenRefresh() {
                long startSecs = 0L;
        long endSecs = startSecs + 10L;
        String tag = "registration-gcm-service";

        OneoffTask oneoff = new OneoffTask.Builder()
                .setService(RegistrationGCMService.class)
                .setTag(tag)
                .setExecutionWindow(startSecs, endSecs)
                .setRequiredNetwork(com.google.android.gms.gcm.Task.NETWORK_STATE_CONNECTED)
                .setRequiresCharging(false)
                .build();

        GcmNetworkManager.getInstance(context.getApplicationContext()).schedule(oneoff);
        L.d(TAG," onTokenRefresh start registration instance id to server");
    }
}