NaikSoftware / StompProtocolAndroid

STOMP protocol via WebSocket for Android
MIT License
597 stars 265 forks source link

Auto-reconnect on network failure #162

Open iormark opened 4 years ago

iormark commented 4 years ago

Hi, Tell me how to make reconnections, for example, when the server or the Internet is unavailable. For example, similar code that works with okhttp and will not work with StompProtocolAndroid.

final OkHttpClient client = new OkHttpClient();
    Flowable<Response> source = Flowable.fromCallable(() -> {
        return client.newCall(new Request.Builder()
            .url("https://google.com/not-found").build()).execute();
    });
    Disposable onComplete = source
            .flatMap(x -> {
                Log.d(TAG, "Response code: " + x.code());
                if (x.code() != 200)
                    return Flowable.error(new IOException("Something went wrong!"));
                else return Flowable.just(x);
            })
             // https://stackoverflow.com/a/25292833
            .retryWhen(new RetryWithDelay(3, 3000))
            .subscribe(
                    x -> Log.d(TAG, "onNext: " + x),
                    Throwable::printStackTrace,
                    () -> Log.d(TAG, "onComplete"));
marcinadd commented 4 years ago

Did you solve the problem?

iormark commented 4 years ago

Unfortunately with this library no.

RafalManka commented 3 years ago

I found a simple soolution for this problem. It's not very elegant, but it works for now:

    private var onReconnected: (() -> Unit)? = null
    private var isDisconnected = false

    private val stompClient: StompClient by lazy {
        Stomp.over(
            Stomp.ConnectionProvider.OKHTTP,
            "ws://server-base-url/endpoint-name/websocket",
            null,
            OkHttpProvider.okHttpClient
        ).apply {
            lifecycle().subscribe { event ->
                if (event?.type == LifecycleEvent.Type.CLOSED) {
                    while (!isConnected) {
                        Thread.sleep(1000)
                        connect()
                    }
                    isDisconnected = true
                } else if (event?.type == LifecycleEvent.Type.OPENED) {
                    if (isDisconnected) {
                        isDisconnected = false
                        onReconnected?.invoke()
                    }
                }
            }
            connect()
        }
    }

  fun startSync() {
        onReconnected = { sync() }
        sync()
    }

    private fun sync() {
        stompClient
            .topic("/topic/endpoint")
            .subscribe({/* do something with your data */})
    }