⚡️Thunder: WebSocket have come through the clouds. | by Jeremy | Aug, 2023
There are a lot of factors to consider when developing a service using WebSockets.
How to make connections, how to maintain connections,
How do you handle network conditions, how do you handle error handling and retry logic, how do you handle asynchronous processing?
There are too many things to consider to develop it.
Therefore, simple structure and intuitiveness are important when developing this kind of library.
From that perspective, Scarlet, the Android WebSocket Library I’ve been using in production, has been very handy and provides a lot of functionality.
Scarlet is a library that manages state internally through a state machine and provides a number of features that make using WebSockets on Android very convenient.
I think it’s worth explaining some of Scarlet’s distinctive features so that you can better understand Thunder, which we’ll talk about later.
1.WebSocket Event Pipeline
As a Retrofit-inspired library, it uses the Dynamic Proxy feature to implement its own WebSocket Event pipeline generation logic based on annotations.
As I understand it, Scarlet is a library that allows you to react reactively to everything that happens to a WebSocket Connection, from opening to closing, by creating a pipeline called a Stream.
@Send
fun request(request: BinanceRequest)@Receive
fun observeEvent(): ReceiveChannel<WebSocket.Event>
@Receive
fun observeTicker(): ReceiveChannel<TickerResponse>
Simply attach a Send or Receive annotation to the interface as shown above, and it will create a web socket connection internally and create a pipeline to serialize and map the data flowing to Binary and String based on the specific return type and annotation.
When I first understand this logic, I think that this is a fancy library.
2.Retries based on connection status
Once a WebSocket connection is opened, messages are sent and received between the server and client.
What if the state of the WebSocket changes due to an error or other circumstances?
Scarlet has made it possible to retry each time the connection is recreated with the code below.
webSocketService.observeEvent() // ReceiveChannel<WebSocket.Event>
.receiveAsFlow()
.filter { it is WebSocket.Event.OnConnectionOpened<*> }
.onEach {
webSocketService.request(BinanceRequest()) // send message (It seems like retry automatically)
}.collect()
}
In the code above, we’re getting the status of Scarlet’s WebSocket.Event through the observeEvent() method, and we’re making sure that we only send the request when the status is OnConnectionOpened.
That is the point, we can retry whenever state(WebSocket.Event) of WebSocket is change.
These are just two of Scarlet’s key points that I focused on while building Thunder, but there are plenty of other features that make it unique, and we hope you’ll try out the library to get a feel for them.