JAVA后台对接苹果APNS(VOIP)实现推送

最近公司需要用苹果APNs实现类似微信视频接电话的效果,查看了苹果官网有VOIP这个东西,于是进行了研究开发。

首先总结一下接入流程:

  1. 在开发者中心申请对应的证书(推送证书,VOIP证书)
  2. IOS 注册推送到APNs(直接调用PushKit 的API即可),回掉中的DeviceToken发送到我们自己的服务端(服务端保存)
  3. 服务器通发送HTTP推送消息请求到APNs服务器。(这一步就是服务器发送推送消息)
  4. IOS接受推送并处理。

BiBi一句。研究任何一样东西首先查看官网资料,千万别怕英文,不知道的单词可以查,虽然我也是个英语小白。不懂的然后再网上搜索资料,这样有利于学习!

苹果开发者中心推送PushKit文档

进入Setting Up a Remote Notification Server
可以看到整个APNs的工作流程。
JAVA后台对接苹果APNS(VOIP)实现推送_第1张图片
下面基于“服务器通发送HTTP推送消息请求到APNs服务器”这一步进行开发。

  • 推送消息描述如下图。大概意思就是App注册,服务端构建消息发送到APNs。认证的方式有两种:
    1、基于Token。使用开发者中心申请的.p8文件和Key ID进行Token认证
    2、基于推送证书,使用.p12证书认证
    JAVA后台对接苹果APNS(VOIP)实现推送_第2张图片
    此处由于公司要求我们使用.p12文件进行开发。

  • 使用pushy进行开发。使用最新包!结合官网进行开发。


   com.turo
   pushy
   0.13.10

下面是我写的一个APNs的一个推送Demo。

@Slf4j
public class APNsUtils {
    private static ApnsClient apnsClient = null;
    public static void main(String[] args) throws Exception {
    //IOS等终端设备注册后返回的DeviceToken
        String deviceToken ="5d7cf67dd6ab56c6d699f86806682e7d99e019216df734f4c57196b84790b718";
//        String deviceToken = "74abd7d51c58a8db995fa53c3508a72481a9d4ad56e7ed1f7d12362f798a6906";
        /**
         * Use the voip push type for notifications that provide information about an incoming Voice-over-IP (VoIP)
         * call. For more information, see Responding to VoIP Notifications from PushKit.
         * If you set this push type, the apns-topic header field must use your app’s bundle ID with .voip
         * appended to the end. If you’re using certificate-based authentication,
         * you must also register the certificate for VoIP services.
         * The topic is then part of the 1.2.840.113635.100.6.3.4 or 1.2.840.113635.100.6.3.6 extension.
         */
         //这是你的主题,大多数情况是bundleId,voip需要在bundleId加上.voip。对应文档中的apns-topic
         //此处可以参考https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns?language=objc
      
        String topic = "com.voip.test.voip";
        String payload = "{ \"aps\" : {\"alert\" : \"测试\", \"sound\" : \"default\", \"badge\" :1},\"liguoxin\":\"liguoxin\" }";
        //有效时间
        Date invalidationTime= new Date(System.currentTimeMillis() + 60 * 60 * 1000L );
        //发送策略 apns-priority 10为立即 5为省电
        DeliveryPriority priority= DeliveryPriority.IMMEDIATE;
        //推送方式,主要有alert,background,voip,complication,fileprovider,mdm
        PushType pushType = VOIP;
        //推送的合并ID,相同的 apns-collapse-id会在App中合并
        String collapseId= UUID.randomUUID().toString();
        //apnsId 唯一标示,如果不传,APNs会给我们生成一个
        UUID apnsId = UUID.randomUUID();
        //构造一个APNs的推送消息实体
        SimpleApnsPushNotification msg = new SimpleApnsPushNotification(deviceToken,topic,payload,invalidationTime,priority,pushType,collapseId,apnsId);
		//开始推送
        PushNotificationFuture<SimpleApnsPushNotification,PushNotificationResponse<SimpleApnsPushNotification>> future = getAPNSConnect().sendNotification(msg);
        PushNotificationResponse<SimpleApnsPushNotification> response = future.get();
        System.out.println(response.getRejectionReason());
        //如果返回的消息中success为true那么成功,否则失败!
        //如果失败不必惊慌,rejectionReason字段中会有失败的原因。对应官网找到原因即可
        //https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/handling_notification_responses_from_apns?language=objc
        
        System.out.println("------------->"+response);
    }

    public static ApnsClient getAPNSConnect() {

        if (apnsClient == null) {
            try {
                /**
                 * Development server: api.sandbox.push.apple.com:443
                 * Production server: api.push.apple.com:443
                 *
                 * api.development.push.apple.com这个域名苹果官网现在找不到了
                 */

                String SANDBOX_APNS_HOST = "api.sandbox.push.apple.com";
//                /Users/liguoxin/Desktop/p12/deve_push.p12
//                 /Users/liguoxin/Desktop/p12/distri_push.p12
               //四个线程
                EventLoopGroup eventLoopGroup = new NioEventLoopGroup(4);
                apnsClient = new ApnsClientBuilder().setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
                        .setClientCredentials(new File("/Users/liguoxin/Desktop/p12/distri_push.p12"),"111111")
                        .setConcurrentConnections(4).setEventLoopGroup(eventLoopGroup).build();


//                EventLoopGroup eventLoopGroup = new NioEventLoopGroup(4);
//                apnsClient = new ApnsClientBuilder().setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
//                        .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File("/Users/liguoxin/Desktop/p12/deve_push.p8"),
//                                "我的temid", "我的keyid"))
//                        .setConcurrentConnections(4).setEventLoopGroup(eventLoopGroup).build();
            } catch (Exception e) {
                log.error("ios get pushy apns client failed!");
                e.printStackTrace();
            }
        }

        return apnsClient;

    }
}

推送结果如下,返回success为true,推送成功。现在查看手机已经收到消息了
JAVA后台对接苹果APNS(VOIP)实现推送_第3张图片

你可能感兴趣的:(博客)