3

I am using OKHttpClient with WebSockets in Android. I want to convert it into reactive programming. How to achieve this. For now i am doing this for WebSocket Connection.

    // OkHttp Client
    OkHttpClient httpClient = new OkHttpClient.Builder().build();

    // WebSocket Object
    Request request = new Request.Builder().url(url).build();
    mWebSocket = httpClient.newWebSocket(request, new WebSocketListener() {
        // Override methods - OnOpen, OnMessage, OnClosing, OnFailure
    }

    // Then Calling this to make websocket request
    mWebSocket.send(message);

I have found this library to use Reactive WebSocket https://github.com/jacek-marchwicki/JavaWebsocketClient

But there is no Callback Listener as 'WebSocketListener' so i can handle the messages.

Any help would be appreciated in this direction. Thanks

Sajid Zeb
  • 1,806
  • 18
  • 32

2 Answers2

0

There is retrofit inspired websocket client by Tinder https://github.com/Tinder/Scarlet

Here apart from sending and receiving regular messages, you can also create a reactive stream to receive Websocket.Event and filter incoming events like onOpen, onMessage, onFailed etc.

Below is an example on how to do that. Goto the link provided above for detailed example

//Service declaration similar to retrofit
interface MyWebsocketService{
    @Receive
    Flowable<WebSocket.Event> observeWebSocketEvent();
}

Scarlet scarletInstance = new Scarlet.Builder()
    .webSocketFactory(OkHttpClientUtils.newWebSocketFactory(okhttpClient,"websocket-server-url")
    .addStreamAdapterFactory(new RxJava2StreamAdapterFactory())
    .build();

MyWebsocketService myWebsocketService = scarletInstance.create<MyWebsocketService>();

myWebsocketService.observeWebsocketEvent()
                  .subscribe(event -> {
                      if(event instanceof Websocket.Event.OnConnectionOpened){
                         //do something here
                      }else if(event instanceof Websocket.Event.OnConnectionClosed){
                        //do something here
                      }
                  });
Maximus
  • 136
  • 1
  • 4
0

I'm not using OkHttp at all, but short answer is put PublishSubject in your OnMessage method. Subject will provide this message to your subscriber and you could also create a chain before subscription.

// OkHttp Client
OkHttpClient httpClient = new OkHttpClient.Builder().build();

// Creating a Subject
// You can use it as Observer or Subscriber
PublishSubject<String> subject = PublishSubject.create();

// WebSocket Object
Request request = new Request.Builder().url(url).build();
mWebSocket = httpClient.newWebSocket(request, new WebSocketListener() {
    @Override
    public void onMessage(String text, ...) {
        subject.onNext(text);
    }
}

// I hope that is an queue option
mWebSocket.send(message);

// Do what you want with your message
Disposable subscription = subject.flatMap(...)
                                 .observeOn(AndroidSchedulers.mainThread())
                                 .subscribe(...);

In sum, it's complicated question because you should handle connection errors, data pressure, config changes and be lifecycle-aware, but it also relevant for non-reactive way (e.g callback-hell), so PublishSubject is a start point.

holdbetter
  • 21
  • 3