9

Apple devices such as iPhones and Macs are able to receive near real-time notifications from the APN system, as well as frequently checking in with the FindMy network, and more. I am wondering how these devices are able to maintain persistent connections with Apple servers.

I assume that Apple devices would not use something like polling, since that would likely eat up battery and waste cellular data. I'm wondering if Apple uses something like WebSockets, or maybe their own proprietary system?

IconDaemon
  • 18,247
  • 10
  • 41
  • 57
cwille97
  • 93
  • 4

3 Answers3

7

TCP/IP socket

The connection is likely a traditional network socket using TCP/IP. A keep-alive option can help maintain a quiet connection.

The interesting problem is how Apple choose to handle the millions of concurrent connections, see the C10K problem and The Secret To 10 Million Concurrent Connections.

Graham Miln
  • 41,742
  • 8
  • 87
  • 120
  • So I suppose they do use long polling then? It sounds to me like they establish the TCP connection and keep it open, and then at some point if it expires the client will re-establish a connection to the server? And regarding C10k, do we have any idea what Apple actually uses this to handle manu connections? Presumably they also rely a lot on horizontal scaling. – cwille97 Feb 06 '22 at 19:00
  • 6
    A raw TCP socket allows data to be sent back and forth arbitrarily. Long polling is only a thing in situations where the server can only respond to the client, rather than sending packets whenever it feels like it (which it can do with plain TCP). – Radvylf Programs Feb 07 '22 at 17:30
7

Each device opens TCP v4 and/or v6 connection(s) over one or more of the following ports.

If you use a firewall or private Access Point Name for cellular data, your Apple devices must be able to connect to specific ports on specific hosts:

  • TCP port 5223 to communicate with APNs.
  • TCP port 443 or 2197 to send notifications to APNs.

TCP port 443 is used during device activation, and afterwards for fallback if devices can't reach APNs on port 5223. The connection on port 443 uses a proxy as long as the proxy allows the communication to pass through without decrypting. The APNs servers use load balancing, so your devices don't always connect to the same public IP address for notifications. It's best to let your device access these ports on the entire 17.0.0.0/8 address block, which is assigned to Apple

On Apple server side, they proxy connection from third party and end user requests to send a notification to another device.

APNs makes every effort to deliver your notifications, and to deliver them with the best user experience:

  • APNs manages an accredited, encrypted, and persistent IP connection to the user’s device.
  • APNs can store notifications for a device that’s currently offline. APNs then forwards the stored notifications when the device comes online.
  • APNs can coalesce notifications with the same bundle ID.

As for the how, Apple silicon efficiency cores and tight integration between the network stack, os, hardware design and power management let the devices sleep much of the time while they are waiting and not busy with other local tasks. Local notifications also serve to wake up the device without needing any network connection.

bmike
  • 226,393
  • 78
  • 398
  • 871
2

Although the existing answers provide a more-or-less accurate description on how this ongoing connection looks like - they describe the feature using terms that are generic (IP, API, TCP+keep-alive) and so on - that may be true - but miss the whole "Apple" face of the thing. These answers could explain both Android and Windows and actually any computing platform maintaining long-term responsive connections.

The important addition I want to add here - is that Apple's "Base OS" - the part shared between MacOS iOS tvOS, watchOS and so on - contains several sub-systems and APIs that allow such behavior practically "for free" to any software developer, provided they use the "recommended" OS subsystems, and not mere generic networking APIs (such as posix etc.)

The ability to maintain long-term responsive connection is not required just by notififaction-based services (like "FindMy" and others - but also for all remote-media services - FaceTime, iTunes, Maps (Navigation) and in reality all their competitors too (Zoom, Viber, Slack, and friends).

One important feature the OP did NOT mention - the ability to survive and renew connection immediately when switching networks, network-stacks and when using multiple networking-stacks and facilities concurrently - is important too. an iPhone can switch from Cellular to WiFi, to Bluetooth and even use all 3 together dozens of times within a single call.

The important mechanisms to learn are:

  • The SystemConfiguration framework (for "Reachability" and non-polling ability to maintain a connection)
  • CFNetwork Framework - the Core Foundation framework implementing most of the low and high level interfaces to network services- where all access via "proxy" or "firewall" or long-term-connection maintenance is implemented
  • NSURLSession - the higher level Swift/Obj-C APIs allowing app developers maintain such connections.

I had to use all three when I developers Audio/Video-Conferencing software, security agents, remote-database-management tools and many others. I always marveled how easy and efficient Apple-provided APIs were in comparison with solutions I built for other platforms.

Just a tiny example: When you "tell the OS" you want to keep connection to specific Server - and be notified on changes in its "Reachability", the OS does this for you - but NOT within your own process. It is an OS service. So... your app can be killed, and be re-launched immediately when connection is re-established. Also - if 3 processes need maintain connection to some domain or service - OS only tracks that domain/service ONCE for all registered "listeners". which also improves efficiency.

So - When you plug Ethernet cable in or out - OS doesn't need to "poll" on the thing - it maintains the interrupt-based hardware anyway. It can be done much more efficiently! same for when you lose Cellular connection.

Last - I recommend on learning these 3 Apple frameworks, and learn how its done on this platform.

A good start can be watching this video from Apple WWDC 2015 - Introducing Network.framework: A modern alternative to Sockets

Motti Shneor
  • 532
  • 2
  • 7
  • Great response. When you say that Apple provides API’s that offer this behavior more or less “for free”, you mean in terms of development cost? It’s already available to use for developers. Not in terms of system resources? Because I imagine maintaining a persistent connection must use *some* resources. – cwille97 Feb 14 '22 at 12:22
  • Thanks @cwille97 Actually... both. goes without saying that development cost drops dramatically when you merely create an NSURLSessionConfiguration object, specify the desired behavior, and... forget about the whole thing. But also - in terms of system resources. The centralized approach, and the access to kernel/driver level information makes most of the polling involved - unnecessary. The only thing OS needs to poll on (in its special low-priority background daemon) is when remote server is down or unresponsive for some reason). All local issues are handled based on interrupts and callbacks. – Motti Shneor Feb 15 '22 at 09:28