You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pushy 0.15.2+Spring Boot发送APNs通知时预发环境网络不可达问题

问题:预发环境使用Pushy发送APNs推送出现网络不可达错误

在Spring Boot项目中使用Pushy 0.15.2版本向iOS设备发送APNs推送通知,本地运行代码一切正常,但部署到预发环境后出现网络不可达错误。

推送代码:

ApnsClientBuilder clientBuilder = new ApnsClientBuilder();
clientBuilder.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST);
clientBuilder.setConnectionTimeout(Duration.ofMillis(60000));
File file = new File(getClass().getClassLoader().getResource("zzzzz").getFile());
clientBuilder.setClientCredentials(file, "yyyyy");

apnsClient = clientBuilder.build();

ApnsPayloadBuilder payloadBuilder = new SimpleApnsPayloadBuilder();
payloadBuilder.setAlertTitle("xxxx");
payloadBuilder.setAlertBody("This is test message");

SimpleApnsPushNotification pushNotification = new SimpleApnsPushNotification(messageDto.getDeviceId(),
        "com.np.gotprint", payloadBuilder.build());
apnsClient.sendNotification(pushNotification).get();

System.out.println("send successfully");

预发环境报错日志:

Caused by: io.netty.channel.AbstractChannel$AnnotatedSocketException: Network is unreachable: api.sandbox.push.apple.com/2620:149:208:304:0:0:0:1f:443
Caused by: java.net.SocketException: Network is unreachable
    at sun.nio.ch.Net.connect0(Native Method)
    at sun.nio.ch.Net.connect(Net.java:454)
    at sun.nio.ch.Net.connect(Net.java:446)
    at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:648)
    at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:83)
    at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:80)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.SocketUtils.connect(SocketUtils.java:80)

排查及解决方案

  • 检查预发环境网络连通性
    预发服务器无法访问苹果沙箱APNs服务器api.sandbox.push.apple.com:443,需确认:

    • 服务器防火墙/安全组是否放行对该域名443端口的出站请求;
    • 错误日志显示的是IPv6地址,若预发环境未配置IPv6网络,可强制Pushy使用IPv4连接,修改客户端构建代码:
      clientBuilder.setPreferredProtocol(Protocol.HTTP_2);
      clientBuilder.setSocketAddressResolver((host, port) -> {
          try {
              InetAddress[] addresses = InetAddress.getAllByName(host);
              // 筛选IPv4地址
              for (InetAddress addr : addresses) {
                  if (addr instanceof Inet4Address) {
                      return new InetSocketAddress(addr, port);
                  }
              }
              //  fallback到第一个地址
              return new InetSocketAddress(addresses[0], port);
          } catch (UnknownHostException e) {
              throw new RuntimeException(e);
          }
      });
      
  • 确认APNs环境匹配
    若预发环境对接的是生产环境的iOS设备,需将APNs服务器切换为生产环境地址:

    clientBuilder.setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST);
    
  • 修复证书文件读取逻辑
    打包成Jar包后,getResource("zzzzz").getFile()可能无法正确读取资源文件,改用流读取方式:

    try (InputStream certStream = getClass().getClassLoader().getResourceAsStream("zzzzz")) {
        clientBuilder.setClientCredentials(certStream, "yyyyy");
    } catch (IOException e) {
        // 处理证书读取异常
        throw new RuntimeException("Failed to load APNs certificate", e);
    }
    
  • 优化异步调用逻辑
    代码中使用get()同步阻塞获取结果,容易引发线程阻塞问题,建议改用异步回调:

    apnsClient.sendNotification(pushNotification)
        .whenComplete((result, error) -> {
            if (error != null) {
                // 处理推送失败
                System.err.println("Push failed: " + error.getMessage());
            } else {
                System.out.println("send successfully");
            }
        });
    

内容的提问来源于stack exchange,提问作者Manish Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:57:18