APNS 那些事!

简介:         之前在消息推送中间件APush里实现了对APNS的桥接,并利用业余时间阅读了官方指南Local and Push Notification Programming Guide,蛮有心得的。稍作总结,分享给大家,希望能够喜欢,欢迎留言讨论! 1.  APNS 通道环境       作为一个黑盒的消息推送服务,APNS为我们提供了开发和产品两套环境,这两套环境除了Host

        之前在消息推送中间件APush里实现了对APNS的桥接,并利用业余时间阅读了官方指南Local and Push Notification Programming Guide,蛮有心得的。稍作总结,分享给大家,希望能够喜欢,欢迎留言讨论!

1.  APNS 通道环境

      作为一个黑盒的消息推送服务,APNS为我们提供了开发和产品两套环境,这两套环境除了Host name不同外,授权证书也不近相同(证书里面会包含APP相关信息,如application bundle ID,在你创建不同的profile的时候,这些信息会自动添加进去),当然Device Token也不同。下面的英文也许能更好地描述这两套环境的不同:

Development: Use the development environment for initial development and testing of the provider application. It provides the same set of services as the production environment, although with a smaller number of server units. The development environment also acts as a virtual device, enabling simulated end-to-end testing.You access the development environment atgateway.sandbox.push.apple.com , outbound TCP port 2195.


Production: Use the production environment when building the production version of the provider application. Applications using the production environment must meet Apple’s reliability requirements.You access the production environment atgateway.push.apple.com , outbound TCP port 2195.

2.  APNS 消息格式

     APNS 采用二进制消息协议,如下:



     看官方的解释,蛮清晰的:


     



     注意:

       如果APNS成功接收到你的消息,它将什么也不返回;

       如果你send a notification that is malformed or otherwise unintelligible, APNs returns an error-response packet and closes the connection. Any notifications that you sent after the malformed notification using the same connection are discarded, and must be resent. 这点要格外重要,所以很多开源工具包,比方说pushy提供了一个FailedConnectionListener,你可以通过实现该接口,方便的实现resent,代码片段如下:

private class MyFailedConnectionListener implements FailedConnectionListener<SimpleApnsPushNotification> {

    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.
        }
    }
}

// ...

pushManager.registerFailedConnectionListener(new MyFailedConnectionListener());

         error-response packet 结构如下:


         Status code 解释如下:

     

      A status code of 10 indicates that the APNs server closed the connection (for example, to perform maintenance).The notification identifier in the error response indicates the last notification that was successfully sent. Any notifications you sent after it have been discarded and must be resent. When you receive this status code, stop using this connection and open a new connection.

3.  APNS 消息接收

     An application must register with Apple Push Notification service for the operating systems on a device and on a computer to receive remote notifications sent by the application’s provider. Registration has three stages:

 3.1 The app registers for remote notifications.

 3.2 The system sets up remote notifications for the app and, if registration is successful, passes a device token to the app delegate.

 3.3 The app sends its device token to the push provider.

 3.4 Device tokens can change. Your app needs to reregister every time it is launched—in iOS by calling the registerForRemoteNotificationTypes: method of UIApplication, and in OS X by calling the registerForRemoteNotificationTypes: method of NSApplication.

 3.5 Because the only notification type supported for non-running applications is icon-badging,pass NSRemoteNotificationTypeBadge as the parameter of registerForRemoteNotificationTypes:.

 3.6 If registration is successful, APNs returns a device token to the device and iOS passes the token to the app delegate in the application:didRegisterForRemoteNotificationsWithDeviceToken: method. If there is a problem in obtaining the token, the operating system informs the delegate by calling the application:didFailToRegisterForRemoteNotificationsWithError: method.

      用一幅图来说明这个流程,如下:



4.  APNS Qos

    Apple Push Notification service includes a default Quality of Service (QoS) component that performs a store-and-forward function.
    If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available.
    Only one recent notification for a particular application is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification is referred to as coalescing notifications.
    If the device remains offline for a long time, any notifications that were being stored for it are discarded.

    注意我字体标黑的这个APNS的特性!

5.  APNS  FAQ

    a. APNS feedback 服务是用来做什么的?

      The Apple Push Notification Service includes a feedback service to give you information about failed push notifications. When a push notification cannot be delivered because the intended app does not exist on the device, the feedback service adds that device’s token to its list. Push notifications that expire before being delivered are not considered a failed delivery and don’t impact the feedback service. By using this information to stop sending push notifications that will fail to be delivered, you reduce unnecessary message overhead and improve overall system performance.
      Query the feedback service daily to get the list of device tokens. Use the timestamp to verify that the device tokens haven’t been reregistered since the feedback entry was generated. For each device that has not been reregistered, stop sending notifications. APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices.    
      The feedback service maintains a separate list for each push topic. If you have multiple apps, you must connect to the feedback service once for each app, using the corresponding certificate, in order to receive all feedback.
      The feedback service has a binary interface similar to the interface used for sending push notifications. You access the production feedback service via feedback.push.apple.com on port 2196 and the development feedback service via feedback.sandbox.push.apple.com on port 2196. As with the binary interface for push notifications, use TLS (or SSL) to establish a secured communications channel. You use the same SSL certificate for connecting to the feedback service as you use for sending notifications. To establish a trusted provider identity, present this certificate to APNs at connection time using peer-to-peer authentication.

      Once you are connected, transmission begins immediately; you do not need to send any command to APNs.Read the stream from the feedback service until there is no more data to read.

      The feedback service’s list is cleared after you read it. Each time you connect to the feedback service, the information it returns lists only the failures that have happened since you last connected.

    b. Best Practices for Managing Connections

       You may establish multiple connections to the same gateway or to multiple gateway instances. If you need to send a large number of push notifications, spread them out over connections to several different gateways.This improves performance compared to using a single connection: it lets you send the push notifications faster, and it lets APNs deliver them faster.
       Keep your connections with APNs open across multiple notifications; don’t repeatedly open and close connections. APNs treats rapid connection and disconnection as a denial-of-service attack. You should leave a connection open unless you know it will be idle for an extended period of time—for example, if you only send notifications to your users once a day it is ok to use a new connection each day.

   c. 接收到APNS消息后,我一般怎么处理呢?

    If your app is frontmost, the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification:method is called on its app delegate;
    If your app is not frontmost or not running, you handle the notifications by checking the options dictionary passed to the application:didFinishLaunchingWithOptions: of your app delegate for either the UIApplicationLaunchOptionsLocalNotificationKey or UIApplicationLaunchOptionsRemoteNotificationKey key.

    实例代码如下:

 (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    // 取得 APNs 标准信息内容
    NSDictionary *aps = [userInfo valueForKey:@"aps"];
    NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
    NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
    NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
     
    // 取得自定义字段内容
    NSString *customizeField1 = [userInfo valueForKey:@"customizeField1"]; //自定义参数,key是自己定义的
    NSLog(@"content =[%@], badge=[%d], sound=[%@], customize field =[%@]",content,badge,sound,customizeField1);
     
    // Required
    [APService handleRemoteNotification:userInfo];
}



//iOS 7 Remote Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
 
    NSLog(@"this is iOS7 Remote Notification");
     
    // Required
    [APService handleRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNoData);
}


d.  消息发送过程中,突然出现Write failed: Broken pipe

   可能因为某种原因,如发送了错误的token,导致Apple强行关闭了SSL连接。跳过最后一次发送的信息,重新连接,继续发送错误信息之后的信息。

e.  因为APNS发送成功没有任何返回,会不会出现是异常但是异常信息还没返回的现象

   有可能,这个时候可以采取批量发送,等候一段时间,比方说1秒,通过Feedback来检查发送状态。

f.   一些你可能会忽视的细节:

      Each application on a device is limited to 64 scheduled local notifications. The system discards scheduled notifications in excess of this limit, keeping only the 64 notifications that will fire the soonest. Recurring notifications are treated as a single notification.

      Custom sounds must be under 30 seconds when played. If a custom sound is over that limit, the default system sound is played instead.

参考文献:

     1. Local and Push Notification Programming Guide

     2. http://www.easyapns.com/apple-delegate

     3. http://blog.csdn.net/tlq1988/article/details/9612237

     4. http://www.cocoachina.com/bbs/read.php?tid=98797


目录
相关文章
|
安全 JavaScript Java
iOS使用PushKit实现VoIP
iOS使用PushKit实现VoIP
1325 0
|
4月前
|
存储 监控 分布式数据库
ClickHouse分布式数据库动态伸缩(弹性扩缩容)的实现
实现ClickHouse数据库的动态伸缩需要持续的维护和精细的操作。从集群配置到数据迁移,再到监控和自动化,每一步都要仔细管理以确保服务的可靠性和性能。这些活动可以显著提高应用的响应性和成本效率,帮助业务根据实际需求灵活调整资源分配。
314 10
|
Java
轻松上手Java字节码编辑:IDEA插件VisualClassBytes全方位解析
本插件VisualClassBytes可修改class字节码,包括class信息、字段信息、内部类,常量池和方法等。
630 6
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
多模态AI核心技术:CLIP与SigLIP技术原理与应用进展
近年来,多模态表示学习在人工智能领域取得显著进展,CLIP和SigLIP成为里程碑式模型。CLIP由OpenAI提出,通过对比学习对齐图像与文本嵌入空间,具备强大零样本学习能力;SigLIP由Google开发,采用sigmoid损失函数优化训练效率与可扩展性。两者推动了多模态大型语言模型(MLLMs)的发展,如LLaVA、BLIP-2和Flamingo等,实现了视觉问答、图像描述生成等复杂任务。这些模型不仅拓展了理论边界,还为医疗、教育等领域释放技术潜力,标志着多模态智能系统的重要进步。
1371 13
多模态AI核心技术:CLIP与SigLIP技术原理与应用进展
|
7月前
|
网络协议 物联网 调度
《探秘鸿蒙分布式软总线:开启无感发现与零等待传输新时代》
鸿蒙系统的分布式软总线技术是实现设备互联互通的核心,通过融合Wi-Fi、蓝牙、NFC等通信技术,实现设备无感发现与零等待传输。该技术具备自发现、自组网、高带宽低时延特性,支持多设备协同工作,如智能家居中手机与音箱、空调的无缝连接,办公场景中的文件共享与多屏协同,以及工业互联网中的实时通信。其极简协议、流式传输和智能调度机制大幅提升效率,为用户带来便捷体验,推动智能生态发展。
469 6
|
9月前
|
机器学习/深度学习 算法 PyTorch
DeepSeek 背后的技术:GRPO,基于群组采样的高效大语言模型强化学习训练方法详解
强化学习(RL)是提升大型语言模型(LLM)推理能力的重要手段,尤其在复杂推理任务中表现突出。DeepSeek团队通过群组相对策略优化(GRPO)方法,在DeepSeek-Math和DeepSeek-R1模型中取得了突破性成果,显著增强了数学推理和问题解决能力。GRPO无需价值网络,采用群组采样和相对优势估计,有效解决了传统RL应用于语言模型时的挑战,提升了训练效率和稳定性。实际应用中,DeepSeek-Math和DeepSeek-R1分别在数学推理和复杂推理任务中展现了卓越性能。未来研究将聚焦于改进优势估计、自适应超参数调整及理论分析,进一步拓展语言模型的能力边界。
1521 8
DeepSeek 背后的技术:GRPO,基于群组采样的高效大语言模型强化学习训练方法详解
记一次 Python 应用开发频繁假死的问题
但是,在测试时,却发现了问题: 当我点击暂停任务后,此时子线程被阻塞。如果我这个时候点击停止,那么就会任务结束。 之后,如果我再点击开始运行,整个应用就会卡死,非常离谱。
|
安全 Java Go
最新进展:Go arena 手动管理内存,鸽了!
最新进展:Go arena 手动管理内存,鸽了!
|
网络协议 Java
如何在Java中使用Socket编程实现TCP连接?
在Java中,通过Socket编程实现TCP连接非常常见。以下演示了基本的TCP通信流程,可根据具体需求进行扩展。
681 0
下一篇
oss云网关配置