简单说下实现苹果通知推送服务(APNs)client的一些要注意的地方:
- 使用长连接;
- sanboxserver是无用的,调试时直接用“gateway.push.apple.com”域名;
- 对于错误的Notification。苹果会回应一个Error response。里面有个identifier,在这个identifier之后的Notification全都失败。
因此发送者要缓存已经发送的Notification,最好设置Notification identifier为增长的整数序列,当收到Error response里,从缓存里取出比Error response的identifier要大的Notification,再次又一次发送。
- 对于一台设备,APNsserver仅仅存储一条Notification。所以假设设备不在线。连续发送多条消息的话。后面的会覆盖前面的;
- Apple的文档里有提到能够设置Notification的Priority = 5,详细是什么意思不太明确。实际測试是当屏幕关闭,在省电时才会接收到的。假设是屏幕亮着,是不会接收到消息的。并且这样的消息是没有声音提示的。貌似意义不大。
特点:
- 支持第三版通知推送,即command = 2。眼下的绝大部分Javaclient都仅仅支持command = 1,即第二版。
- 支持SSL握手成功才返回,能够调用 pushManager.start().sync(); 等待握手成功。
- 最大限度重试发送,内部自己主动处理重连,错误重发机制;
- 支持配置RejectListener,即通知被Appleserver拒绝之后的回调接口;
- 支持配置ShutdownListener,即当shutdown时,没有发送完的消息处理的回调接口。
- 支持发送统计信息;
- 实现组件分离,能够利用PushClient。FeedbackClient来写一些灵活的代码。
- Notification发送者能够自定义设置发送的Queue,自己灵活处理堵塞。超时等问题。
把Queue暴露给发送者,这严格来说是一个不好的设计。由于在shutdown里,有可能别的线程还在put notification到queue里。
可是由于APNs协议本身,包含消息推送机制本身就是一个不全然靠谱的东东。考虑到发送者处理堵塞,消息积压的便利性,因此把Queue暴露给发送者。
代码地址:
样例:
public class MainExample { public static void main(String[] args) throws InterruptedException { Environment environment = Environment.Product; String password = "123456"; String keystore = "/home/hengyunabc/test/apptype/app_type_1/productAPNS.p12"; PushManager pushManager = new PushManagerImpl(keystore, password, environment); //set a push queue BlockingQueue<Notification> queue = new LinkedBlockingQueue<Notification>(8192); pushManager.setQueue(queue ); //waiting for SSL handshake success pushManager.start().sync(); //build a notification String token = "5f6aa01d8e3358949b7c25d461bb78ad740f4707462c7eafbebcf74fa5ddb387"; Notification notification = new NotificationBuilder() .setToken(token) .setBadge(1) .setPriority(5) .setAlertBody("xxxxx").build(); //put notification into the queue queue.put(notification); TimeUnit.SECONDS.sleep(10); //get statistic info Statistic statistic = pushManager.getStatistic(); System.out.println(statistic); } }