Tag: apple push notifications

如何可靠,高效地读取Java Server中Apple推送通知服务器的所有错误响应?

我正在研究Java中的Apple推送通知的服务器端开发。 我正在使用增强格式,以便检测失败的消息并重新发送跟踪错误消息的消息。 我知道Apple不保证Push Notifications的发送,但我希望能够知道Apple是否收到了我的消息以及是否包含任何错误。 我注意到当我尝试向Apple发送无效消息(无效设备令牌,太大的有效负载等等)时,我可以在套接字关闭之前发送更多消息。 当套接字关闭时,从Apple读取错误代码为时已晚,所以我不知道哪条消息是坏消息(或者即使有错误的消息,因为Apple说连接可能偶尔会关闭,即使没有错误)。 我在JavaPNs源中看到的处理此问题的方法是在发送每条消息(或消息组)后立即读取Apple的响应。 如果频繁执行则从套接字读取,并在没有任何内容可读的情况下等待超时。 如果您不经常发送推送通知,这是可以接受的。 如果您尝试以高频率发送大量通知(比方说每秒数百个),则无法在每条消息之后停止等待来自Apple的响应(即使您等待的响应时间仅为20毫秒,限制你每秒50条消息,你无法知道Apple写错误响应需要多长时间,所以短暂的等待可能还不够。 如果您在每条消息之后没有停止阅读可能的错误,那么在向Apple发送消息期间您的连接可能会被关闭,在这种情况下,您将无法获得导致连接关闭的消息的ID 。 我正在考虑的另一种方法是在单独的线程中执行读取和写入。 通过这种方式,我可以更好地从Apple获取错误消息(在连接关闭之前),而不会影响我向Apple发送消息的速度。 这种方法在编程上更复杂,并且由于我的服务器需要将APN发送到多个iOS应用程序,每个应用程序都需要自己的套接字和读取器/写入器线程,这将使我需要的线程数增加两倍。 在尝试向Apple的沙盒服务器发送推送通知时,学习了APN服务器的所有上述行为。 我不确定Apple的生产服务器的行为是否更好,我不确定在生产服务器上执行测试是个好主意。 我的问题 – 有没有办法在关闭连接之前可靠地读取Alpha的错误响应,而不会牺牲性能? 是否有可能以某种方式从服务器关闭后从套接字读取输入?

通过Java使用Apple推送通知服务

我试图实现一个Java程序,它将Apple推送通知发送到iPhone客户端应用程序…找到以下库: Java APN 提供者代码: 创建以下代码(来自Javapns)以在我的应用程序中使用: try { PayLoad payLoad = new PayLoad(); payLoad.addAlert(“My alert message”); payLoad.addBadge(45); payLoad.addSound(“default”); PushNotificationManager pushManager = PushNotificationManager.getInstance(); pushManager.addDevice(“iPhone”, “f4201f5d8278fe39545349d0868a24a3b60ed732”); log.warn(“Initializing connectiong with APNS…”); // Connect to APNs pushManager.initializeConnection(HOST, PORT, “/etc/Certificates.p12”, “password”, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12); Device client = pushManager.getDevice(“Lambo”); // Send Push log.warn(“Sending push notification…”); PushNotificationManager.getInstance().sendNotification(client, payLoad); } catch (Exception e) { throw new […]

Java APNS(Apple推送通知服务)错误

我正在尝试使用Java APNS(一个开源项目)向iPhone发送推送通知。 但是我收到了一个错误。 我使用.pem文件作为证书。 这应该是.p12文件吗? 我不确定区别是什么,但我在网上看到这些文件格式之间存在差异。 这是代码: ApnsService service = APNS.newService() .withCert(“gpk.pem”, “XXXX”) .withSandboxDestination() .build(); String payload = APNS.newPayload().alertBody(“Can’t be simpler than this!”).build(); String token = “theTokenIsRemoveHere”; service.push(token, payload); 这是错误: Exception in thread “main” com.notnoop.exceptions.InvalidSSLConfig: java.io.IOException: toDerInputStream rejects tag type 45 at com.notnoop.apns.internal.Utilities.newSSLContext(Utilities.java:102) at com.notnoop.apns.ApnsServiceBuilder.withCert(ApnsServiceBuilder.java:161) at com.notnoop.apns.ApnsServiceBuilder.withCert(ApnsServiceBuilder.java:124) at com.geomobsters.cli.ApnsClient.main(ApnsClient.java:12) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at […]

Java TLS套接字:找不到可信证书

让我快速解释一下我正在做什么。 我正在尝试在java中构建我自己的Apple推送通知服务(用于测试目的)。 这项服务得益于TLS套接字。 我有一个java客户端来创建一个TLS套接字来向APN发送推送通知。 我更改了主机URL以将套接字重定向到localhost:2195。 现在我正在尝试编写一个java套接字服务器来获取通知请求。 但是,我在握手期间遇到exception,无法找到解决方法。 注意:我在双方都使用相同的证书,它是一个标准的.p12文件,用于向APN发送推送通知。 这是客户端(简化): KeyStore ks = KeyStore.getInstance(“PKCS12”); ks.load(new FileInputStream(certificatePath), password.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(“sunx509”); kmf.init(ks, password.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(“sunx509”); tmf.init((KeyStore)null); SSLContext sc = SSLContext.getInstance(“TLS”); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLSocketFactory ssf = sc.getSocketFactory(); SSLSocket socket = (SSLSocket) ssf.createSocket(InetAddress.getLocalHost(), 2195); socket.startHandshake(); 这是服务器: KeyStore ks = KeyStore.getInstance(“PKCS12”); ks.load(new FileInputStream(certificatePath), password.toCharArray()); KeyManagerFactory kmf […]

通过Java与Apple Push Notification Server进行SSL握手

您好我正在尝试使用Java向我的设备发送推送消息。 但是我在建立ssl连接时已经遇到了问题。 这是到目前为止的代码: KeyStore keyStore = KeyStore.getInstance(“PKCS12”); InputStream key = getClass().getResourceAsStream(“apns-dev-key.p12”); char[] c = key.toString().toCharArray(); keyStore.load(getClass().getResourceAsStream(“apns-dev-cert.p12”), c); KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(“SunX509”); keyMgrFactory.init(keyStore, c); SSLContext sslContext = SSLContext.getInstance(“TLS”); sslContext.init(keyMgrFactory.getKeyManagers(), null, null); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port); String[] cipherSuites = sslSocket.getSupportedCipherSuites(); sslSocket.setEnabledCipherSuites(cipherSuites); sslSocket.startHandshake(); 我得到的错误是: java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: […]

获取javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure错误

我正在尝试使用Java-pns向iPhone发送推送通知但我收到以下错误 – javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure 我的代码是 – String token=”95076d2846e8979b46efd1884206a590d99d0f3f6139d947635ac4186cdc5942″; String host = “gateway.sandbox.push.apple.com”; int port = 2195; String payload = “{\”aps\”:{\”alert\”:\”Message from Java o_O\”}}”; NotificationTest.verifyKeystore(“res/myFile.p12”, “password”, false); KeyStore keyStore = KeyStore.getInstance(“PKCS12”); keyStore.load(getClass().getResourceAsStream(“res/myFile.p12”), “password”.toCharArray()); KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(“SunX509”); keyMgrFactory.init(keyStore, “password”.toCharArray()); SSLContext sslContext = SSLContext.getInstance(“TLS”); sslContext.init(keyMgrFactory.getKeyManagers(), null, null); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port); String[] […]

Java套接字和丢弃的连接

检测套接字是否被丢弃的最合适方法是什么? 或者是否确实发送了数据包? 我有一个库,可以通过Apple gatways( 在GitHub上提供 )向Apple发送Apple推送通知。 客户端需要打开套接字并发送每条消息的二进制表示; 但不幸的是,Apple没有任何回复。 连接可以重复使用以发送多条消息。 我正在使用简单的Java Socket连接。 相关代码是: Socket socket = socket(); // returns an reused open socket, or a new one socket.getOutputStream().write(m.marshall()); socket.getOutputStream().flush(); logger.debug(“Message \”{}\” sent”, m); 在某些情况下,如果在发送消息时或之前删除了连接; Socket.getOutputStream().write()成功完成。 我预计这是由于TCP窗口尚未耗尽。 有没有办法可以确定数据包是否实际进入网络? 我尝试了以下两种解决方案: 插入额外的socket.getInputStream().read()操作,超时250ms。 这会强制在删除连接时失败的读取操作,否则会挂起250ms。 将TCP发送缓冲区大小(例如Socket.setSendBufferSize() )设置为消息二进制大小。 这两种方法都有效,但它们会严重降低服务质量; 吞吐量最多从100条消息/秒到大约10条消息/秒。 有什么建议么? 更新: 受到多个答案的质疑,质疑所描述的可能性。 我构建了我所描述的行为的“单元”测试。 查看Gist 273786的单元案例。 两个unit testing都有两个线程,一个服务器和一个客户端。 客户端发送数据时服务器关闭,而不会抛出IOException。 这是主要方法: public static […]

无法使用Javapns / Javaapns SSL握手失败发送推送通知

我有推送通知的问题。 我有一个由团队成员创建的p.12证书,我有要推送到的设备的设备令牌。 我正在使用javapns库来执行推送(也尝试了相同结果的javaapns lib)但我不断收到此错误: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632) at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) at java.io.OutputStream.write(OutputStream.java:58) at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:402) at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:350) at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:320) at javapns.Push.sendPayload(Push.java:177) at javapns.Push.combined(Push.java:100) at PushTest.push(PushTest.java:43) at PushTest.main(PushTest.java:25) 这是我用来测试的代码 try { List n = Push.combined(text, 20, null, file, “********”, false, token); for (PushedNotification notification […]