I’ve been spending quite a bit of time lately exploring the world of real-time notifications. Naively, I was under the impression that real-time communication meant one thing: WebSockets.
More specifically, I thought the term for server to browser communication was “WebSocket.” I thought this for years! I even wrote a 5-part series on WebSockets on the subject thinking that’s what the term meant (it’s a good series, I actually do recommend it).
It wasn’t until I started researching the protocol as part of my day job that I realized I was wrong. Like, way wrong. There are several ways to get data from a server to a browser outside of WebSockets.
Today we’re going to cover four of the most popular stateful mechanisms: WebSockets, gRPC, MQTT, and Server-Sent Events (SSE). Each of these is unique in the way they facilitate server to client messages, with pros and cons to consider before you implement a solution.
As I mentioned earlier, there is a long list of notification methods but we’ll focus on the four most popular ones. I mentioned they were stateful, and it’s worth describing what that means.
A stateful connection is a persistent connection between two entities that remembers previous interactions. As long as the connection is up, the two entities can communicate freely back and forth with each other, much like being on a phone call. When one side hangs up, the connection is terminated, and they can no longer communicate with each other.
Compare this to a stateless communication mechanism like Amazon SNS or other Webhook implementation where the connection is not persistent and the communication is one-way. These are intended to be used as a response to an event and inform subscribers without maintaining a continuous connection or keeping memory of previous interactions.
Back to our notification methods:
Now that we know what each of these are, we should talk about when to use them. As with any question in software, the answer of course is it depends, but as a general guideline, let’s take a look at certain situations where each one is the most appropriate.
Of course you can use these communication mechanisms for other use cases, but generally you will find them best suited for the tasks mentioned above.
We all know I’m an AWS guy, so when AWS has a managed service for something I will typically use it (well, at least try it out for posterity). Below are your options if you’re looking to implement one of these communication mechanisms in AWS.
Testing server-to-client communications typically has been a tricky task. Personally, I’ve built server-side workflows that emit events and had to write custom scripts that connect, sit, and wait for the client to do assertions. It’s a whole big thing and not a particularly easy way to validate your code. That said, I’ve found an easier alternative for testing when doing development work.
Now, all these options are for manual testing, which really only scales when you are in active development. But being able to guess and check your work as you build is a huge productivity boost.
For WebSockets, you can add your endpoint and auth headers, hit Connect and go. This was an invaluable resource for me to debug when I was implementing WebSockets via Amazon API Gateway.
If you’re building an app that communicates with IoT devices, the MQTT option in Postman will let you select which topics to subscribe to along with the Quality of Service (QOS) for each. You can even configure the Last Will and Testament for the connection to test that out too.
The gRPC request testing capabilities are complete as well, allowing you to import a .proto definition file for your schema and add metadata to your messages. You can run assertions via an After response script that can check for things like specific metadata or trailers.
The simplest one which makes you go why didn’t I think of that is server-sent events. Since SSE just uses an HTTP connection, you can use a standard HTTP request in Postman to setup the connection. It will manage the connection and stream the events in the response section as they come in.
I’ve yet to find a good, managed solution for automated testing in a CI pipeline. For now, I’m sticking with custom scripts when I absolutely have to do it. It’s an overhead that you’ll need to consider when building your notification mechanisms.
There’s a reason there is so much support for real-time notifications: they are important! These types of notifications are quickly becoming a de facto standard and if your application doesn’t implement one of them, you’re likely falling behind. It’s something users are inadvertantly beginning to assume exist as part of a core feature set. They don’t want to wait or reload pages.
The world has gone async, and real-time notifications are the tool that ties it all back to your users.
If you’re looking to get started, you have lots of options:
There’s not a right or wrong way to implement real-time notifications (don’t quote me on that). All of us have our own unique business needs that make one mechanism more advantageous over another. The best thing you can do is go out and try. Don’t be afraid to iterate. See what works well for you, meets your latency SLAs, and provides a maintainable code base for your devs over the life of your app.
Good luck and if you have any questions, feel free to reach out!