zoukankan      html  css  js  c++  java
  • 转:IOS 基于APNS消息推送原理与实现(JAVA后台)

    Push的原理:
    Push 的工作机制可以简单的概括为下图
     
    图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider。
    APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。
    上图可以分为三个阶段。
    第一阶段:Push服务器应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。
    第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
    第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。
     
    从上图我们可以看到。
    1、首先是应用程序注册消息推送。
    2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。
    3、应用程序将deviceToken发送给PUSH服务端程序。
    4、 服务端程序向APNS服务发送消息。
    5、APNS服务将消息发送给iPhone应用程序。
    无论是iPhone客户端跟APNS,还是Provider和APNS都需要通过证书进行连接的。下面介绍一下所用到证书的制作。
    一、CSR文件

    1、生成Certificate Signing Request(CSR)
     
     
    2、填写你的邮箱和常用名称,并选择保存到硬盘。
     
    点击继续:
     
    这样就在本地生成了一个PushTest.certSigningRequest文件。


    二、SSL certificate文件

    1、用你付过费的帐号登录到iOS Provisioning Portal,并创建Certificates(已创建可省略),如下图:
     
     
     
     
     
     
     
     
    点击Submit
     
     
    创建Certificate完毕。
    2、新建一个App ID
    点击New App ID
     
     
    输入Description,Bundle Identifier,点击Submit,新建App ID完毕。
     
     
     
    找到新建的App ID 点击右侧的Configure:
     
     
    Development Push SSL Certificate ,与Production Push SSL Certificate 区别在于一个是用于开发的推送证书,一个是用于发布产品的推送证书。两个证书获取到的终端deviceToken是不一样的,用两个证书生成的P12证书用于JAVA后台连接APNS的服务器地址也是不同的,Development Push SSL Certificate 对应连接的服务器地址是:gateway.sandbox.push.apple.com。Production Push SSL Certificate  对应连接的服务器地址是:gateway.push.apple.com。
    点击Development Push SSL Certificate一行后的Configure:
     
     
    点击Continue:
     
     
    选择前面生成好的PushTest.certSigningRequest文件,点击Generate,出现如下所示的页面:
     
    点击Continue:
     
    点击Download,下载生成的支持推送服务的证书(命名为:aps_development-6.cer)。

    点击Done,你会发现状态变成了Enabled:
     
     
    到现在为止,我们已经生成了两个文件:
    1、PushTest.certSigningRequest
    2、aps_development-6.cer(下载生成的支持推送服务的证书。)
    双击aps_development-6.cer注册到你的钥匙串中,这样你的钥匙串中就会有
     
    三、准备profile证书,因为推送消息只能在真机上测试,所以要建一个profile证书
     
    点击"new profile"为上面新建的APP ID建个profile ,成功之后下载pushtestdescDevprofile.mobileprovision
     
     
    双击将其加入到xcode 的Provisioning Profiles 中。
    四、生成JAVA后台用于连接APNS的证书:
    打开钥匙串
     
     
     
    选中Apple Development IOS Push Services:com.easecom.zhwgpushtestdesc,右键将其导出。
     
     
    导出用于JAVA后台连接APNS的P12证书。
     
    输入p12 证书的密码,本文中我用的是123456。记住这个密码,JAVA后台使用p12证书的时候要用到。
     
     
    输入访问钥匙串的密码:系统登陆密码。
     
     
    导出PushTest.p12证书完毕。
    到现在为止,我们已经生成了四个文件:
    1、PushTest.certSigningRequest
    2、aps_development-6.cer(下载生成的支持推送服务的证书。)
    3、pushtestdescDevprofile.mobileprovision
    4、PushTest.p12
    至此IOS消息推送(JAVA后台)证书全部制作完毕。
    下面开始上代码:
    五、IOS端代码:
    1、首先在项目的AppDelegate.m中加入以下两个代理方法
    复制代码
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
        NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
        //获取终端设备标识,这个标识需要通过接口发送到服务器端,服务器端推送消息到APNS时需要知道终端的标识,APNS通过注册的终端标识找到终端设备。
        NSLog(@"My token is:%@", token);   
    }  
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {   
        NSString *error_str = [NSString stringWithFormat: @"%@", error];   
        NSLog(@"Failed to get token, error:%@", error_str);   
    }
    复制代码

    2、在AppDelegate.m的(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中加入注册消息通知推送能力;加入当应用程序处于未启动状态时,判断是否由远程消息通知触发;加入清除消息推送通知标记。

    复制代码
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      //判断是否由远程消息通知触发应用程序启动
        if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]!=nil) {
            //获取应用程序消息通知标记数(即小红圈中的数字)
            int badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
            if (badge>0) {
               //如果应用程序消息通知标记数(即小红圈中的数字)大于0,清除标记。
                badge--;
              //清除标记。清除小红圈中数字,小红圈中数字为0,小红圈才会消除。
                [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
            }
        }
        //消息推送注册
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge];
    }
    3、在项目AppDelegate.m中加入消息接收处理代理方法。
    //处理收到的消息推送
    - (void)application:(UIApplication *)application 
    didReceiveRemoteNotification:(NSDictionary *)userInfo
    {
        //在此处理接收到的消息。
        NSLog(@"Receive remote notification : %@",userInfo);
    }
    复制代码

    六、JAVA后台代码:

    复制代码
    public static void main(String[] args) throws Exception 
    {
            try
            {
                //从客户端获取的deviceToken,在此为了测试简单,写固定的一个测试设备标识。
               String deviceToken = "df779eda 73258894 5882ec78 3ac7b254 6ebc66fe fa295924 440d34ad 6505f8c4"
                System.out.println("Push Start deviceToken:" + deviceToken);
                //定义消息模式
                PayLoad payLoad = new PayLoad();
                payLoad.addAlert("this is test!");
                payLoad.addBadge(1);//消息推送标记数,小红圈中显示的数字。
                payLoad.addSound("default");
                //注册deviceToken
                PushNotificationManager pushManager = PushNotificationManager.getInstance();
                pushManager.addDevice("iPhone", deviceToken);
                //连接APNS
                String host = "gateway.sandbox.push.apple.com";
                //String host = "gateway.push.apple.com";
                int port = 2195;
                String certificatePath = "c:/PushTest.p12";//前面生成的用于JAVA后台连接APNS服务的*.p12文件位置
                String certificatePassword = "123456";//p12文件密码。
                pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
                //发送推送
                Device client = pushManager.getDevice("iPhone");
                System.out.println("推送消息: " + client.getToken()+"
    "+payLoad.toString() +" ");
                pushManager.sendNotification(client, payLoad);
                //停止连接APNS
                pushManager.stopConnection();
                //删除deviceToken
                pushManager.removeDevice("iPhone");
                System.out.println("Push End");
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
    }
    }
    复制代码
    至此大功告成,测试通过。
    以上在Iphone4,IPAD2设备测试通过,Iphone3g,3gs需要打PushDoctor(推送医生)补丁才能测试通过。
    花开花谢春不管,水暖水寒鱼自知.
  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/guoxiaoqian/p/4784287.html
Copyright © 2011-2022 走看看