Real-time data and Reactive Programming

Part 2: Client Side Reactivity

Ken Hom
3 min readJun 27, 2021
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:

import { fromEvent } from 'rxjs';const el = document.getElementById('my-element')!;// Create an Observable that will publish mouse movements
const mouseMoves = fromEvent<MouseEvent>(el, 'mousemove');
// Subscribe to start listening for mouse-move events
const subscription = mouseMoves.subscribe(evt => {
// Log coords of mouse movements
console.log(`Coords: ${evt.clientX} X ${evt.clientY}`);
// When the mouse is over the upper-left of the screen,
// unsubscribe to stop listening for mouse movements
if (evt.clientX < 40 && evt.clientY < 40) {
subscription.unsubscribe();
}
});

(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:

checking
checking
checking
checking
checking
sending
receiving
received: string("hello!!!")
let's do some mapping here
Mapped data: string("HELLO!!!").
checking
checking
checking
checking
checking
checking
disconnecting
Received completion: finished.

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.

--

--