How to write a WebSocket App with Scarlet in 3 minutes

How to write a WebSocket App with Scarlet in 3 minutes

In mobile applications, the data layer is the source of truth for what is displayed on the screen. However, when the WebSocket API was integrated in Tinder earlier this year, maintaining it became a headache. To make WebSocket integration easier on Android, Scarlet was created.

WebSocket is one of the options for implementing the data layer in Android applications, especially when the application needs to update data in real time, such as chat, online multiplayer games, and real-time feeds. It establishes a two-way connection between the client and the server. When the connection is open, they can send text and binary messages back and forth with low overhead. This article will teach you how to quickly implement WebSocket in your Android application.

set up

To implement Scarlet, first add it to your app/build.gradle file.

  1. dependencies {
  2. ...
  3. // scarlet
  4. implementation 'com.tinder.scarlet:scarlet:0.1.12'  
  5. }

In the example provided by Scarlet, RxJava is used to help manage the flow of data sent by the web socket. Implement it in app/build.gradle.

  1. dependencies {
  2. // rx
  3. implementation 'io.reactivex.rxjava2:rxjava:2.2.21'  
  4. implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'  
  5. implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'  
  6. }

If you are curious about Coroutine and Kotlin Flow support, see here: https://github.com/Tinder/Scarlet/issues/114

Now the important part of our setup is the service. We can test our WebSocket using websocket-echo (wss://websocket-echo.glitch.me);

Create interface function

Next, create an interface to define the functions for communicating with the WebSocket.

  1. interface EchoService {
  2.  
  3. @Receive
  4. fun observeConnection(): Flowable<WebSocket.Event>
  5.  
  6. @Send
  7. fun sendMessage(param: String)
  8. }

As shown above, the service interface looks very similar to Retrofit. You can use the @Receive annotation to observe the data stream from the WebSocket and use @Send to send or subscribe to data to the WebSocket.

With the service set up, we can move on to implementing the service in our activity; in this case, I didn’t use any architecture and just implemented the service in the Activity.

  1. class MainActivity : AppCompatActivity() {
  2. ...
  3. private fun setupWebSocketService() {
  4. webSocketService = provideWebSocketService(
  5. scarlet = provideScarlet(
  6. client = provideOkhttp(),
  7. lifecycle = provideLifeCycle(),
  8. streamAdapterFactory = provideStreamAdapterFactory(),
  9. )
  10. )
  11. }
  12.      
  13. private fun provideWebSocketService(scarlet: Scarlet) = scarlet. create (EchoService::class.java)
  14.      
  15. private fun provideScarlet(
  16. client: OkHttpClient,
  17. lifecycle: Lifecycle,
  18. streamAdapterFactory: StreamAdapter.Factory,
  19. ) =
  20. Scarlet.Builder()
  21. .webSocketFactory(client.newWebSocketFactory(ECHO_URL))
  22. .lifecycle(lifecycle)
  23. .addStreamAdapterFactory(streamAdapterFactory)
  24. .build()
  25.              
  26. private fun provideOkhttp() =
  27. OkHttpClient.Builder()
  28. .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor. Level .BASIC))
  29. .build()
  30.              
  31. private fun provideLifeCycle() = AndroidLifecycle.ofApplicationForeground(application)
  32.      
  33. private fun provideStreamAdapterFactory() = RxJava2StreamAdapterFactory()
  34. ...
  35. }

test

Now we can test the code by sending something to the WebSocket. The WebSocket will send the same messages as they were received.

  1. class MainActivity : AppCompatActivity() {
  2. ...
  3.    
  4. private fun sendMessage(message: String) {
  5. webSocketService.sendMessage(message)
  6. adapter.addItem(Message(message = message, isFromSender = true ))
  7. }
  8.      
  9. @SuppressLint( "CheckResult" )
  10. private fun observeConnection() {
  11. webSocketService.observeConnection()
  12. .observeOn(AndroidSchedulers.mainThread())
  13. .subscribe({ response ->
  14. Log.d( "observeConnection" , response.toString())
  15. onReceiveResponseConnection(response)
  16. }, { error ->
  17. Log.e( "observeConnection" , error.message.orEmpty())
  18. Snackbar.make(binding.root, error.message.orEmpty(), Snackbar.LENGTH_SHORT).show()
  19. })
  20. }
  21.  
  22. private fun onReceiveResponseConnection(response: WebSocket.Event) {
  23. when (response) {
  24. is OnConnectionOpened<*> -> changeToolbarTitle( "connection opened" )
  25. is OnConnectionClosed -> changeToolbarTitle( "connection closed" )
  26. is OnConnectionClosing -> changeToolbarTitle( "closing connection.." )
  27. is OnConnectionFailed -> changeToolbarTitle( "connection failed" )
  28. is OnMessageReceived -> handleOnMessageReceived(response.message)
  29. }
  30. }
  31.  
  32. private fun handleOnMessageReceived(message: MessageScarlet) {
  33. adapter.addItem(Message(message.toValue(), false ))
  34. binding.etMessage.setText( "" )
  35. }
  36.  
  37. private fun MessageScarlet.toValue(): String {
  38. return   when (this) {
  39. is Text -> value
  40. is Bytes -> value.toString()
  41. }
  42. }
  43.      
  44. ...
  45. }

Summarize

That’s all for this article. Scarlet is a great library that gives you access to implementing WebSockets in your Android app. You can easily set up Scarlet for your app with the tutorial above, especially if you’re already familiar with tools like Retrofit.

<<:  WeChat official announcement: Mini Program regular review is suspended during the Spring Festival and will resume on February 7

>>:  New version of mobile QQ released! This is the first update after the Ministry of Industry and Information Technology took transitional administrative guidance on Tencent

Recommend

The evolution and thinking of Taobao Native R&D model

The origin and development of DX DX was hatched f...

Can the “Head-Down Method” really cure cervical spondylosis?

In recent years, the incidence of cervical spondy...

Operational methodology in 2019!

In just over ten days, we will officially say goo...

A mad scientist who ate 720 eggs in one month had a surprising ending.

Eggs are synonymous with nutrition. They are eate...

The "Kappa duck" that lays eggs and produces milk is blocked by the dam

The platypus is probably one of the most bizarre ...

Side job: 2 hours a day working on Pinduoduo and earning 3,000 yuan a month

Side job: 2 hours a day working on Pinduoduo and ...

Omnichannel Promotion | How to find an effective user interaction strategy?

With the development of technological trends, a c...

VR manufacturers, have you ever considered Hawking’s feelings?

Last week, within less than a day of opening his ...

I hope I can write such good copy!

What these copywritings have in common is: they a...