读书人

基于Java的 iOS 多线程推送通报

发布时间: 2012-11-10 10:48:51 作者: rapoo

基于Java的 iOS 多线程推送通知
一,iOS 推荐原理

iOS 上的远程通知推荐机制,在官方的开发文档 《 Local and Push Notification Programming Guide》上已经有很清楚的描述。

下面再复习下这份指引的上的图,清晰下概念。

1. 消息流图

基于Java的 iOS 多线程推送通报


1.1 Provider 发送通知到 APNS (Apple Push Notification Server,苹果推送通知服务器)

1.2 APNS 发送通知到具体的 iOS 设备

1.3 iOS系统,通知到具体应用。

其中,Provider 是APP服务端的消息发出端,这部分是需要用户实现的事情,也是用户唯一可控的地方,其它流程完全在于苹果构建的系统的效率。


2. 总体消息流

基于Java的 iOS 多线程推送通报


从上面可以看到 APNS 的角色,是管理了 APNS 到每一个具体设备的长连接,而不是每个 Provider 到 每个 app 的长连接。这种方式的设计是基于 iOS 设备上的资源使用考虑,只要保留一个网络长连接就好,所有的 App 的通知都是通过这个长连接来推送通知。另一个方面,则是简化了整个流程的设计难度。


3. 设备到 APNS 的可信任长连接

基于Java的 iOS 多线程推送通报


4. Provider 到 APNS 的可信任连接

基于Java的 iOS 多线程推送通报


5. Token 的注册

基于Java的 iOS 多线程推送通报

注意到:已经安装的 APP, 在 APNS 注册到 Token 之后,是要有发送到 APP Provider 即,App 自己的服务器上,见下面一点:


6. Token 流

基于Java的 iOS 多线程推送通报


二,本文前提

1. 已经在 Provider 上已经记录了所安装的 APP 已经注册的设备的 Token

2. 相关的密钥,权限方面已经配置好

3. Provider 是基于 JavaPNS 的实现, JavaPNS 项目位于: http://code.google.com/p/javapns


三,代码

package com.zhenian.app.service;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.FutureTask;import javapns.Push;import javapns.communication.exceptions.CommunicationException;import javapns.communication.exceptions.KeystoreException;import javapns.notification.PushedNotification;import javapns.notification.ResponsePacket;import org.springframework.stereotype.Service;@Servicepublic class NotificationEngine  {    // 10 个线程在后台发送通知    public static final int EXCE_THREAD_POOL_SIZE = 10;    private void shutdownEngine(){        System.out.println("------------shutdownEngine-----------------------------");        // 关闭 ExecutorService        if(!exec.isShutdown()){            exec.shutdown();        }    }    public void init(){        // 注册 jvm 关闭时操作        Runtime.getRuntime().addShutdownHook(new Thread(){            public void run() {                .NotificationEnginethis.shutdownEngine();            }        });    }        public void destroy(){        Thread t = new Thread(){            public void run() {                NotificationEngine.this.shutdownEngine();            }        };        t.start();    }        private ExecutorService exec = Executors.newFixedThreadPool(EXCE_THREAD_POOL_SIZE);        private FutureTask<List<PushedNotification>> doSendNotificationList(final String message, final int badge, final String sound, final String keystore, final String password, final boolean production, final List<String> tokens){            // 带返回结果发送动作        FutureTask<List<PushedNotification>> future = new FutureTask<List<PushedNotification>>(                new Callable<List<PushedNotification>>() {                    public List<PushedNotification> call() {                        List<PushedNotification> notifications = null;                        try {                            notifications = Push.combined(message,badge,sound,keystore,password,production,tokens);                        } catch (CommunicationException e) {                            e.printStackTrace();                        } catch (KeystoreException e) {                            e.printStackTrace();                        }                        return notifications;                    }                });        // 提交到执行框架执行        exec.submit(future);        return future;    }        public void sendNotificationList(final String message, final int badge, final String sound, final String keystore, final String password, final boolean production, final List<String> tokens){            FutureTask<List<PushedNotification>> futrue = doSendNotificationList(message, badge,sound,keystore,password,production,tokens);        try {            // 阻塞至接收到返回结果。            List<PushedNotification> list = futrue.get();            for (PushedNotification notification : list) {                if (notification.isSuccessful()) {                        /* Apple accepted the notification and should deliver it */                          System.out.println("Push notification sent successfully to: " + notification.getDevice().getToken());                        /* Still need to query the Feedback Service regularly */                  } else {                        String invalidToken = notification.getDevice().getToken();                        /* Add code here to remove invalidToken from your database */                          /* Find out more about what the problem was */                          Exception theProblem = notification.getException();                        //theProblem.printStackTrace();                        log.error(theProblem.toString());                        /* If the problem was an error-response packet returned by Apple, get it */                          ResponsePacket theErrorResponse = notification.getResponse();                        if (theErrorResponse != null) {                                log.error(theErrorResponse.getMessage());                        }                }            }        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }            }}

四,说明

1. 可以集成到 Java EE 应用之中

2. 也可以建立一个后台服务执行

3. JavaPNS 请参考相关文档。


THE END











读书人网 >操作系统

热点推荐