APNS 接受推送消息,但它们永远不会到达目标
APNS accepts push messages, but they are never come to target
我正在尝试为我的后端服务器服务添加苹果推送通知,但我遇到了一个我无法理解的问题。
我正在使用 Pushy 库 (com.relayriders.pushy).
我的代码就像他们的 github 页面推荐的那样。
代码是有效的,没有例外,推送看起来像是正确形成的。推送发送到 APNS,但永远不会到达设备。
设备令牌和证书是正确的,我的朋友通过他的测试程序向目标设备发送了推送。
我还测试了 com.notnoop.apns 库,结果相同 - 没有例外,仍然没有推送到设备
这是我的发件人 class:
package ua.asprelis.communicator.push;
import com.relayrides.pushy.apns.ApnsEnvironment;
import com.relayrides.pushy.apns.FailedConnectionListener;
import com.relayrides.pushy.apns.PushManager;
import com.relayrides.pushy.apns.PushManagerConfiguration;
import com.relayrides.pushy.apns.RejectedNotificationListener;
import com.relayrides.pushy.apns.RejectedNotificationReason;
import com.relayrides.pushy.apns.util.ApnsPayloadBuilder;
import com.relayrides.pushy.apns.util.MalformedTokenStringException;
import com.relayrides.pushy.apns.util.SSLContextUtil;
import com.relayrides.pushy.apns.util.SimpleApnsPushNotification;
import com.relayrides.pushy.apns.util.TokenUtil;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLHandshakeException;
public class ApplePushNotifier
{
private final PushManager<SimpleApnsPushNotification> pushManager;
private final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
public ApplePushNotifier() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException, IOException {
URL url = getClass().getResource("/certpath/cert.p12");
this.pushManager = new PushManager<>(
ApnsEnvironment.getSandboxEnvironment(),
SSLContextUtil.createDefaultSSLContext(URLDecoder.decode(url.getPath(), "UTF-8"), "password"),
null, // Optional: custom event loop group
null, // Optional: custom ExecutorService for calling listeners
null, // Optional: custom BlockingQueue implementation
new PushManagerConfiguration(),
"ExamplePushManager");
pushManager.start();
pushManager.registerRejectedNotificationListener(new MyRejectedNotificationListener());
pushManager.registerFailedConnectionListener(new MyFailedConnectionListener());
}
public void sendpush(String message, byte[] token) throws InterruptedException {
String payload = payloadBuilder.setAlertBody(message).setSoundFileName("ring-ring.aiff").buildWithDefaultMaximumLength();
pushManager.getQueue().put(new SimpleApnsPushNotification(token, payload));
}
public void sendpush(String message, String stoken) throws InterruptedException, MalformedTokenStringException {
byte[]token = TokenUtil.tokenStringToByteArray(stoken);
String payload = payloadBuilder.setAlertBody(message).setSoundFileName("ring-ring.aiff").buildWithDefaultMaximumLength();
SimpleApnsPushNotification notification = new SimpleApnsPushNotification(token, payload);
pushManager.getQueue().put(notification);
System.out.println("Queued: "+notification);
}
public void closeSender() {
if(pushManager!=null) {
try {
pushManager.shutdown();
} catch (InterruptedException ex) {
Logger.getLogger(ApplePushNotifier.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private class MyRejectedNotificationListener implements RejectedNotificationListener<SimpleApnsPushNotification> {
@Override
public void handleRejectedNotification(
final PushManager<? extends SimpleApnsPushNotification> pushManager,
final SimpleApnsPushNotification notification,
final RejectedNotificationReason reason) {
System.out.format("%s was rejected with rejection reason %s\n", notification, reason);
}
}
private class MyFailedConnectionListener implements FailedConnectionListener<SimpleApnsPushNotification> {
@Override
public void handleFailedConnection(
final PushManager<? extends SimpleApnsPushNotification> pushManager,
final Throwable cause) {
if (cause instanceof SSLHandshakeException)
// This is probably a permanent failure, and we should shut down the PushManager.
else
System.out.println(cause);
}
}
}
并为 运行 测试 class 推送:
@Test
public void testPushMessage() {
Random random = new Random();
String testMessage = "Hello Test! "+random.nextInt(1000);
String testToken = "e6878d3993abfaec48220b9d4d3ea0b576c22351c7fbbb5faeb5449bf7f24452";
//e6878d39 93abfaec 48220b9d 4d3ea0b5 76c22351 c7fbbb5f aeb5449b f7f24452
ApplePushNotifier notifier=null;
try {
notifier = new ApplePushNotifier();
notifier.sendpush(testMessage, testToken);
} catch(Exception ex) {
Logger.getLogger(applePushNotifierTest.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (notifier!=null)
notifier.closeSender();
}
}
我的输出:
[main] INFO com.relayrides.pushy.apns.PushManager - ExamplePushManager starting.
Queued: SimpleApnsPushNotification [token=[-26, -121, -115, 57, -109, -85, -6, -20, 72, 34, 11, -99, 77, 62, -96, -75, 118, -62, 35, 81, -57, -5, -69, 95, -82, -75, 68, -101, -9, -14, 68, 82], payload={"aps":{"alert":"Hello Test! 955","sound":"ring-ring.aiff"}}, invalidationTime=null, priority=IMMEDIATE]
[main] INFO com.relayrides.pushy.apns.PushManager - ExamplePushManager shutting down.
我觉得问题出在一些我看不到的小块上。如果两个测试库都不起作用,那就奇怪了
正如我所说 - 我犯了一个愚蠢的错误。我真是个笨蛋。我用了
ApnsEnvironment.getSandboxEnvironment()
而不是
ApnsEnvironment.getProductionEnvironment()
在两个库中。
那是我第一次使用 APNS。
我正在尝试为我的后端服务器服务添加苹果推送通知,但我遇到了一个我无法理解的问题。
我正在使用 Pushy 库 (com.relayriders.pushy).
我的代码就像他们的 github 页面推荐的那样。
代码是有效的,没有例外,推送看起来像是正确形成的。推送发送到 APNS,但永远不会到达设备。
设备令牌和证书是正确的,我的朋友通过他的测试程序向目标设备发送了推送。
我还测试了 com.notnoop.apns 库,结果相同 - 没有例外,仍然没有推送到设备
这是我的发件人 class:
package ua.asprelis.communicator.push;
import com.relayrides.pushy.apns.ApnsEnvironment;
import com.relayrides.pushy.apns.FailedConnectionListener;
import com.relayrides.pushy.apns.PushManager;
import com.relayrides.pushy.apns.PushManagerConfiguration;
import com.relayrides.pushy.apns.RejectedNotificationListener;
import com.relayrides.pushy.apns.RejectedNotificationReason;
import com.relayrides.pushy.apns.util.ApnsPayloadBuilder;
import com.relayrides.pushy.apns.util.MalformedTokenStringException;
import com.relayrides.pushy.apns.util.SSLContextUtil;
import com.relayrides.pushy.apns.util.SimpleApnsPushNotification;
import com.relayrides.pushy.apns.util.TokenUtil;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLHandshakeException;
public class ApplePushNotifier
{
private final PushManager<SimpleApnsPushNotification> pushManager;
private final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
public ApplePushNotifier() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException, IOException {
URL url = getClass().getResource("/certpath/cert.p12");
this.pushManager = new PushManager<>(
ApnsEnvironment.getSandboxEnvironment(),
SSLContextUtil.createDefaultSSLContext(URLDecoder.decode(url.getPath(), "UTF-8"), "password"),
null, // Optional: custom event loop group
null, // Optional: custom ExecutorService for calling listeners
null, // Optional: custom BlockingQueue implementation
new PushManagerConfiguration(),
"ExamplePushManager");
pushManager.start();
pushManager.registerRejectedNotificationListener(new MyRejectedNotificationListener());
pushManager.registerFailedConnectionListener(new MyFailedConnectionListener());
}
public void sendpush(String message, byte[] token) throws InterruptedException {
String payload = payloadBuilder.setAlertBody(message).setSoundFileName("ring-ring.aiff").buildWithDefaultMaximumLength();
pushManager.getQueue().put(new SimpleApnsPushNotification(token, payload));
}
public void sendpush(String message, String stoken) throws InterruptedException, MalformedTokenStringException {
byte[]token = TokenUtil.tokenStringToByteArray(stoken);
String payload = payloadBuilder.setAlertBody(message).setSoundFileName("ring-ring.aiff").buildWithDefaultMaximumLength();
SimpleApnsPushNotification notification = new SimpleApnsPushNotification(token, payload);
pushManager.getQueue().put(notification);
System.out.println("Queued: "+notification);
}
public void closeSender() {
if(pushManager!=null) {
try {
pushManager.shutdown();
} catch (InterruptedException ex) {
Logger.getLogger(ApplePushNotifier.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private class MyRejectedNotificationListener implements RejectedNotificationListener<SimpleApnsPushNotification> {
@Override
public void handleRejectedNotification(
final PushManager<? extends SimpleApnsPushNotification> pushManager,
final SimpleApnsPushNotification notification,
final RejectedNotificationReason reason) {
System.out.format("%s was rejected with rejection reason %s\n", notification, reason);
}
}
private class MyFailedConnectionListener implements FailedConnectionListener<SimpleApnsPushNotification> {
@Override
public void handleFailedConnection(
final PushManager<? extends SimpleApnsPushNotification> pushManager,
final Throwable cause) {
if (cause instanceof SSLHandshakeException)
// This is probably a permanent failure, and we should shut down the PushManager.
else
System.out.println(cause);
}
}
}
并为 运行 测试 class 推送:
@Test
public void testPushMessage() {
Random random = new Random();
String testMessage = "Hello Test! "+random.nextInt(1000);
String testToken = "e6878d3993abfaec48220b9d4d3ea0b576c22351c7fbbb5faeb5449bf7f24452";
//e6878d39 93abfaec 48220b9d 4d3ea0b5 76c22351 c7fbbb5f aeb5449b f7f24452
ApplePushNotifier notifier=null;
try {
notifier = new ApplePushNotifier();
notifier.sendpush(testMessage, testToken);
} catch(Exception ex) {
Logger.getLogger(applePushNotifierTest.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (notifier!=null)
notifier.closeSender();
}
}
我的输出:
[main] INFO com.relayrides.pushy.apns.PushManager - ExamplePushManager starting.
Queued: SimpleApnsPushNotification [token=[-26, -121, -115, 57, -109, -85, -6, -20, 72, 34, 11, -99, 77, 62, -96, -75, 118, -62, 35, 81, -57, -5, -69, 95, -82, -75, 68, -101, -9, -14, 68, 82], payload={"aps":{"alert":"Hello Test! 955","sound":"ring-ring.aiff"}}, invalidationTime=null, priority=IMMEDIATE]
[main] INFO com.relayrides.pushy.apns.PushManager - ExamplePushManager shutting down.
我觉得问题出在一些我看不到的小块上。如果两个测试库都不起作用,那就奇怪了
正如我所说 - 我犯了一个愚蠢的错误。我真是个笨蛋。我用了
ApnsEnvironment.getSandboxEnvironment()
而不是
ApnsEnvironment.getProductionEnvironment()
在两个库中。
那是我第一次使用 APNS。