The apps use OS/platform push for notifications, because the webapp component is asleep at the time. When the app is active, its just the regular webapp, which uses eventsource.
The JMAP spec provides for eventsource and webhooks, but obviously an individual provider can offer more than that via an extension. When we do switch over to JMAP, we'll continue to use our custom method to register platform notifications.
It's not "just" use websockets. These may be intercepted by proxies with connection limits, timeouts or just plain not understanding websockets at all.
You will need to detect this and apply a fallback mechanism.
Which goes back to the point of this post: easy in theory. Much harder in practice.
Where I work we ended up using Microsoft's signalr-library to avoid having to learn and tackle all of these issues ourselves.
Yet we still needed to add some additional Band-Aids around the libraries provided to be able to support all cases we wanted seamlessly.