`
RamosLi
  • 浏览: 120065 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

最好用的Java APNS类库

阅读更多
    我在公司的项目组一直都在做一款ios应用,涉及到聊天功能,当用户在线时,可以使用长连接将消息推送过去,但应用可能并不处于运行中,比如用户关闭应用,或者切换到后台10分钟后应用会停止运行。如果这时需要给用户推送消息,那怎么办呢?此时就需要用到APNS(Apple Push Notification Service),网上关于APNS的介绍一大堆,这里就不做过多叙述了。大概是这么一个过程:我的server将消息发到苹果的服务器(APNS Server),苹果服务器再将消息转发到用户的iphone上,iphone收到消息后再弹窗提示用户。我们需要做的就是将消息发给APNS Server。下图是iphone收到通知后的截屏:
 

      我是Java码农,网上比较流行的Java APNS的类库主要有两个:1. JavaPNS. 2.Java APNS(notnoop)  
 
    JavaPNS优点是简单,但缺点也很明显,效率不高,没有考虑各种通知发送出错的情况。这个库适合那些每天通知发送量特别小,并且用户收没收到也无所谓的应用。
 
    notnoop的Java APNS就要强大很多,目前它应该是使用最多的Java类库。我们也用了将近一年,但随着使用的加深,发现它有很多不完善之处。最严重的问题是,运行一段时间后就死掉了,通知再也发不出去了,但重启下就又恢复了。经查,应该是死锁了,通知堆积在内存中并没有真正发出去。这对于对消息送达率和及时性要求非常高的聊天软件来说,是不能忍受的。因此,打算重写,自己实现!
 
    在这个背景下,dbay-apns-for-java 开源项目应运而生。目前已经放到了Github上供大家下载,中英双语注释,力争每个人都看的懂,地址:https://github.com/RamosLi/dbay-apns-for-java
 
    dbay-apns4j 吸取了其他类库的优点,修正了不足之处,更是将一些极端情况都考虑进去了。比如跟APNS Server建立的长连接,对方可能会单方面关闭连接(connection_idle),此时会造成通知发送看起来成功其实失败的情况,dbay-apns4j也考虑到了。
 
    目前,已经在我的Server上运行一段时间,每天需要发送上百万的消息,表现良好。我自信这是目前最好的Java APNS类库,欢迎大家下载使用,也欢迎指出一些不足之处。
 
    另外:关于APNS的一些深入研究,我在上篇文章中已经写出来了,地址:http://ramosli.iteye.com/admin/blogs/1940843
  • 大小: 682.5 KB
8
1
分享到:
评论
52 楼 ron.luo 2016-03-23  
kingtaozi 写道
thl1229 写道
duzhanxiaosa 写道
使用了你提供的java-apns后报
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: dev-1 Send success. count: 1, notificaion: id=101 token=a891e6f4a0028c808b4e19a0363373435bc218140585f914c6de583de1a9162e payload={"aps":{"sound":"default.caf","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl$1 run
严重: dev-1 Unexpected command or size. commend: 0 , size: -1

这是怎么回事?



我也遇到你这情况,请问你是怎么解决的啊?

这个问题有人解决了吗,求指点

config.setDevEnv(true);这里配置Apns环境,true代表开发环境,false代表生成环境。
51 楼 ron.luo 2016-03-23  
kingtaozi 写道
thl1229 写道
duzhanxiaosa 写道
使用了你提供的java-apns后报
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: dev-1 Send success. count: 1, notificaion: id=101 token=a891e6f4a0028c808b4e19a0363373435bc218140585f914c6de583de1a9162e payload={"aps":{"sound":"default.caf","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl$1 run
严重: dev-1 Unexpected command or size. commend: 0 , size: -1

这是怎么回事?



我也遇到你这情况,请问你是怎么解决的啊?

这个问题有人解决了吗,求指点

还是没有人解决么?
50 楼 kingtaozi 2016-02-19  
thl1229 写道
duzhanxiaosa 写道
使用了你提供的java-apns后报
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: dev-1 Send success. count: 1, notificaion: id=101 token=a891e6f4a0028c808b4e19a0363373435bc218140585f914c6de583de1a9162e payload={"aps":{"sound":"default.caf","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl$1 run
严重: dev-1 Unexpected command or size. commend: 0 , size: -1

这是怎么回事?



我也遇到你这情况,请问你是怎么解决的啊?

这个问题有人解决了吗,求指点
49 楼 王健小二 2015-12-29  
请问下我在使用时socket.write的时候报错,异常为:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122) at java.io.OutputStream.write(OutputStream.java:75) at com.dbay.apns4j.impl.ApnsConnectionImpl.sendNotification(ApnsConnectionImpl.java:167) at com.dbay.apns4j.impl.ApnsConnectionImpl.sendNotification(ApnsConnectionImpl.java:123) at com.dbay.apns4j.impl.ApnsServiceImpl$1.run(ApnsServiceImpl.java:69) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745)Caused by: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:384) at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:134) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.secur


我的环境是spring + mvn+ tomcat7

但是我直接通过main方法是没有问题的,不知道有人遇到这个情况没有,希望能有人帮帮我
48 楼 ceekay_ 2015-12-16  
你们的不会报超时异常吗? 另这个东西是异步的吗?
47 楼 ccq502849336 2015-12-08  
作者你好!
    我这里运行出现如下错误,请问是怎么回事????
十二月 08, 2015 10:08:30 上午 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: pro-2 Send success. count: 1, notificaion: id=102 token=945021cc9d1b9feec5cdff0a9b46da7372b8c45239159c7c22e9828dd775c5d3 payload={"aps":{"sound":"","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
十二月 08, 2015 10:08:30 上午 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: pro-1 Send success. count: 1, notificaion: id=101 token=945021cc9d1b9feec5cdff0a9b46da7372b8c45239159c7c22e9828dd775c5d3 payload={"uid":123456,"aps":{"sound":"G:\/Workspaces\/MyEclipse 9\/TestDbayAPNS\/mp3\/msg.mp3","alert":"How are you?","badge":1},"type":12}
十二月 08, 2015 10:08:30 上午 com.dbay.apns4j.impl.ApnsConnectionImpl run
严重: pro-2 Socket operation on nonsocket: recv failed
java.net.SocketException: Socket operation on nonsocket: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at java.io.InputStream.read(InputStream.java:101)
at com.dbay.apns4j.impl.ApnsConnectionImpl$1.run(ApnsConnectionImpl.java:258)
at java.lang.Thread.run(Thread.java:744)

十二月 08, 2015 10:08:30 上午 com.dbay.apns4j.impl.ApnsConnectionImpl run
严重: pro-1 Socket Closed
java.net.SocketException: Socket Closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at java.io.InputStream.read(InputStream.java:101)
at com.dbay.apns4j.impl.ApnsConnectionImpl$1.run(ApnsConnectionImpl.java:258)
at java.lang.Thread.run(Thread.java:744)
46 楼 tdizi 2015-12-07  
为什么打开APP时候收不到推送消息,只有在后台运行时候才能收到消息呢!
45 楼 zhuhai 2015-11-14  
jianxiang.yi 写道
不错,实测没有什么问题,运行了好几天,不会内存泄露

我用了,不到一天消息就发布出去了,情况和notnoop/java-apns的一样能分享一下你是怎么用的吗
44 楼 jianxiang.yi 2015-11-09  
不错,实测没有什么问题,运行了好几天,不会内存泄露
43 楼 dangzhao 2015-10-14  

下载了代码,很不错!

只是收到消息后手机上没有 badge 提示


{"uid":123456,"aps":{"sound":"","alert":"How are you ?","badge":1},"type":1}
json串应该是没有问题,楼主空闲时分析下可能是什么原因?
42 楼 molebinn 2015-09-24  
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:889)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at java.io.InputStream.read(InputStream.java:101)
at com.dbay.apns4j.impl.ApnsFeedbackConnectionImpl.getFeedbacks(ApnsFeedbackConnectionImpl.java:62)
at com.dbay.apns4j.impl.ApnsServiceImpl.getFeedbacks(ApnsServiceImpl.java:149)
at com.dbay.apns4j.demo.Apns4jDemo.main(Apns4jDemo.java:62)

我遇到你这情况,请问你是怎么解决的啊?
41 楼 fortunateGoder 2015-08-18  
我想问一下,怎么控制badge的值,因为你的代码是设置一个特定的值,而不是递增的,所以我想咨询一下你们在后台是怎么设置这个值的
40 楼 programming 2015-08-11  
java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded
        at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1978)
        at java.security.KeyStore.load(KeyStore.java:1445)
        at com.dbay.apns4j.tools.ApnsTools.createSocketFactory(ApnsTools.java:123)
        at com.dbay.apns4j.impl.ApnsServiceImpl.<init>(ApnsServiceImpl.java:55)
        at com.dbay.apns4j.impl.ApnsServiceImpl.createInstance(ApnsServiceImpl.java:128)
        at xxx.PushDaemon.start(PushDaemon.java:62)
        at xxx.Main.main(Main.java:40)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
        at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
        at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
        at com.sun.crypto.provider.PKCS12PBECipherCore.implDoFinal(PKCS12PBECipherCore.java:399)
        at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40.engineDoFinal(PKCS12PBECipherCore.java:506)
        at javax.crypto.Cipher.doFinal(Cipher.java:2165)
        at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1969)
        ... 6 more
Exception in thread "main" java.lang.RuntimeException: Can't create socketFactory.
        at com.dbay.apns4j.tools.ApnsTools.createSocketFactory(ApnsTools.java:136)
        at com.dbay.apns4j.impl.ApnsServiceImpl.<init>(ApnsServiceImpl.java:55)
        at com.dbay.apns4j.impl.ApnsServiceImpl.createInstance(ApnsServiceImpl.java:128)
        at xxx.PushDaemon.start(PushDaemon.java:62)
        at xxx.Main.main(Main.java:40)


39 楼 thl1229 2015-06-23  
duzhanxiaosa 写道
使用了你提供的java-apns后报
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: dev-1 Send success. count: 1, notificaion: id=101 token=a891e6f4a0028c808b4e19a0363373435bc218140585f914c6de583de1a9162e payload={"aps":{"sound":"default.caf","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl$1 run
严重: dev-1 Unexpected command or size. commend: 0 , size: -1

这是怎么回事?



我也遇到你这情况,请问你是怎么解决的啊?
38 楼 duzhanxiaosa 2015-06-16  
使用了你提供的java-apns后报
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl sendNotification
信息: dev-1 Send success. count: 1, notificaion: id=101 token=a891e6f4a0028c808b4e19a0363373435bc218140585f914c6de583de1a9162e payload={"aps":{"sound":"default.caf","alert":{"loc-args":["Jenna","Frank"],"loc-key":"GAME_PLAY_REQUEST_FORMAT"},"badge":1}}
2015-6-16 16:35:07 com.dbay.apns4j.impl.ApnsConnectionImpl$1 run
严重: dev-1 Unexpected command or size. commend: 0 , size: -1

这是怎么回事?
37 楼 lwm0522003 2015-06-09  
好是好.但是在程序中我无法控制是否重发,无法得知是否发送成功.假如我要在服务器关闭前将还未发送或者发送失败的存到DB中,在下次server启动的时候再发送.要实现这个使用你的框架就不知道怎么办了.
36 楼 greatwqs 2015-02-07  
增加了APNSDelegate, 麻烦review一下,
主要是ApnsConnectionImpl.java的290行代码添加有没有问题;

https://github.com/greatwqs/dbay-apns-for-java
35 楼 greatwqs 2015-02-07  
ramosli, 我这边看了一下你的代码,有一点关于DeviceToken失效的情况想与你讨论一下:
明白可以从feedback中获取失效的DeviceToken, 但是有轮询数据库DeviceToken发送一种公共消息时, 总有一些失效的DeviceToken,
用https://github.com/notnoop/java-apns时可以实现一个ApnsDelegate, 失效时可以把失效的DeviceToken更新到数据库;

我查询了线上的APNS发送失败的LOG, 碰巧的是全部都是DeviceToken失效引起的;
如果失效的DeviceToken越来越多, 大概会影响PUSH的效率(频繁关闭socket);

可否在源码这个地方加入更新DeviceToken无效的ApnsDelegate类似实现方法?
(也有很多地方没有看完, 不知道是否合适)
34 楼 xiaoxuechen1 2015-01-22  
你好,请问feedback没有内容是怎么回事?
发送给错误的token,feedback还是没有内容,只能在打印信息中看到错误信息。
请问有什么好的方法获取到错误信息呢?
33 楼 li4haoo 2015-01-19  
你好  我想问一下 群发推送 是怎么设置呢 我是小白 请指教 这几天都在研究你这个东西

相关推荐

    iphone消息推送APNS

    **苹果推送通知服务(Apple Push Notification service,简称APNS)** APNS是苹果公司提供的一项服务,用于向iOS、iPadOS、watchOS、tvOS以及macOS设备推送通知。通过APNS,应用开发者可以在他们的应用不在前台运行...

    苹果消息推送 java端

    - 在Java中,有多个第三方库可以帮助我们与APNs交互,例如`Apns4j`、`JavaAPNS`和`ApnsPushNotification`等。这些库通常提供了API,简化了证书管理、构建推送消息和处理反馈等功能。 4. **推送消息结构**: - 一...

    javapns-jdk

    在文件名“javapns-jdk16-163.jar”中,".jar"是Java Archive的缩写,它是Java平台下用于打包和部署类库的标准格式。这意味着这个文件是一个可直接在Java环境中使用的库,包含了JavaPNS的代码和其他依赖,以便开发者...

    基于Java的即时通信软件

    1. **Java基础知识**:Java的核心特性包括平台独立性(JVM使得Java代码可以在任何支持Java的设备上运行)、面向对象编程(OOP)以及丰富的类库。在开发即时通信软件时,开发者可以利用Java的多线程特性来处理并发...

    Java+XML日程提醒系统.7z

    Java的类库丰富,支持网络通信、多线程、数据库连接等多种功能,这使得Java成为开发跨平台应用程序的理想选择。 XML,全称为eXtensible Markup Language,是一种标记语言,用于描述数据的结构和内容。与HTML不同,...

    仿QQ开发的即时通讯软件

    Java的基础语法、类库和设计模式都是开发此类应用的基础。 2. **Socket编程**:即时通讯的核心在于网络通信,Java中的Socket编程提供了客户端和服务器端通信的能力。通过创建Socket连接,服务器可以接收并处理来自...

    xiaoyuantong

    Java的类库丰富,提供了大量用于网络通信、数据库连接、图形用户界面(GUI)构建的API,这对于构建一个功能全面的校园信息系统非常有利。 在"校园通"程序中,教务管理部分可能利用了Java的集合框架来存储和操作学生...

    jsp iOS推送的包

    3. **commons-lang-2.1.jar**:Apache Commons Lang是Java的一个工具类库,包含了一系列实用的工具方法,增强了Java的内置类。在处理推送服务时,可能会用到字符串操作、数组处理等工具。 4. **...

    Teacher-student-corner:大学课程的师生交流应用

    Java是一种广泛使用的面向对象的编程语言,以其跨平台性、安全性以及强大的类库支持而著称。在开发此类应用时,Java的Swing或JavaFX库可以用于构建用户界面,提供丰富的图形元素和交互功能。此外,Java的多线程特性...

    information-release-sys:信息发布系统

    在这个过程中,Java作为强大的后端开发语言,以其优秀的跨平台性能和丰富的类库,为系统的构建提供了坚实的基础。 在Java中,信息发布系统可能采用MVC(Model-View-Controller)架构模式,这种模式可以清晰地分离...

    CommitNotifier

    Java是一种跨平台的、面向对象的编程语言,具有丰富的类库和强大的性能,适合开发这样的桌面应用程序。 3. **事件监听和处理**:为了在SVN仓库有新的提交时发送通知,CommitNotifier需要实现事件监听机制。这可能...

    XamChat:适用于iOS和Android的简单聊天应用程序

    通过这些库,开发者可以使用C#创建原生的iOS和Android界面,同时利用.NET类库来实现应用程序的后端功能。 **XamChat应用结构** 在XamChat项目中,我们可能会看到以下主要组成部分: 1. **用户界面(UI)**:...

Global site tag (gtag.js) - Google Analytics