Real-time data and Reactive Programming

Part 2: Client Side Reactivity

Photo by Aron Visuals on Unsplash

When you have so many microservices each with their own db technology, and a data lake for analytics and analysis across a large company, then it really helps to not have to wait for those refresh cycles discussed in Part 1, especially if within that setup you maybe have data of one system being displayed to the user of another.

A parallel and related trend in the frontend is to have real-time UI updates (Reactive Programming). Some popular libraries such as rxjs and Combine help implement this style where state changes are published and read similar to what we saw in the Kafka messages.

There are many examples of this but here is one straight out of RxJS in Angular where mouse move events are able to be subscribed to and processed with different operators:

(https://angular.io/guide/rx-library)

The fromEvent method creates an Observable to which you can subscribe and perform callbacks on every emission.

Reacting to server messages

Changes don’t have to stem from user events but can also be data changes from a backend maybe sent from the server web sockets perhaps. This changes your app’s communication style from a “pull based” style to a “push” based style, ideal for multiple clients.

Lets say you want to do this in an iOS app. Apple’s been working on the new Combine framework which is their version of Rx<***>. Here is something I wrote which can let you use a Publisher/PassthroughSubject in conjunction with web sockets. I got the idea from RxJS’s webSocketSubject (https://rxjs.dev/api/webSocket/webSocket) which is a really nice wrapper that isn’t really talked about too often.

From what I’ve tried, it looks like you can use URLSessionWebSocketTask which maybe can wrap into a Publisher/PassthroughSubject to use with Combine.

It does use polling via a Timer and fires off every second to check for new messages, which some may think defeats the purpose of a socket, but I dont know that there is another way to do that without tapping into SwiftNIO or something.

Feel free to throw this in a playground and see it for yourself! Here’s the output I had:

I would love to see someone try to use this to live-update SwiftUI state! If it works maybe we can make a Swift Package from it.