Retrofit + Rxjava takes long time to invoke onError when server connection failed

安稳与你 提交于 2019-12-06 02:33:03

问题


I'm using Retrofit + Rxjava to get a list of entities from server, by my design when the task fails, first it checks Internet connection and after that it checks the connection to the server in doOnError method of Observable.

When Client is not connected to the Internet doOnError is invoked in a reasonable time and user get the error message but the problem is when Internet is connected and I get wrong port or domain (to check the server problem error) It takes a long time (about 1 min or longer) and it's really annoying. How can I reduce this time and what's the reason?

how I check Internet and Server connection :

public static boolean checkConnection(String ipOrUrl, int port) {
    try {
        int timeoutMs = 100;
        Socket socket = new Socket();
        SocketAddress soketAddress = new InetSocketAddress(ipOrUrl, port);
        socket.connect(soketAddress, timeoutMs);
        socket.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

how I try to get list of entities :

    foodgetRetorfitService.getRestaurants()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
//here I'm checking the internet and server connection in the onlineTask if retrofit fail
//and if clients get Online this ( getRestaurantFromServer ) is called again.
            .doOnError(error -> {
                error.printStackTrace();
                NetworkUtils.doOnlineTask(new OnlineTask() {
                    public void doWhenOnline() {
                        getResturantsFromServer();
                    }
                }, true);
            })
            .subscribe(new Observer<List<Restaurant>>() {
                @Override
                public void onNext(List<Restaurant> restaurants) {
                    restaurantItemAdapter.updateAdapterData(restaurants);
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "onError: rxjava and retrofit error : can't get restaurant list");
                    e.printStackTrace();
                }
            });

how doOnlineTask is Implemented

    public static void doOnlineTask(OnlineTask onlineTask, boolean autoRetry, int retryTimeout) {
        NetworkUtils.isOnline(autoRetry)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnError(error -> {
//here I check the Exception type ( I raised them when checking the connection )
                    if (error instanceof InternetConnectionException)
                        onlineTask.doWhenInternetFaild();

                    if (error instanceof ServerConnectionException)
                        onlineTask.doWhenServerFaild();
                })
                .retryWhen(t -> t.delay(2, TimeUnit.SECONDS))
                .subscribe(result -> {
                            if (result.equals(NetworkStatus.CONNECTED))
                                onlineTask.doWhenOnline();
                            else {
                                if (result.equals(NetworkStatus.INTERNET_FAILD))
                                    onlineTask.doWhenInternetFaild();
                                else if (result.equals(NetworkStatus.SERVER_FAILD))
                                    onlineTask.doWhenInternetFaild();
                            }
                        }, error -> error.printStackTrace()
                );
    }

onlineTask is just an abstract class

abstract public void doWhenOnline();

public void doWhenInternetFaild() {
   //implemented somehow
}


public void doWhenServerFaild() {
   //implemented somehow
}

What I tried :

I guessed it's timeout problem so I changed Retrofit timeout with OkHttpClient and It does not worked. also I changed timeouts set by myself and I reduced them. not working.


回答1:


I assume you are using OkHttp client to go with Retrofit. What you are looking for is most probably a connection timeout.

You can set different timeouts when building a client.

OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build();


来源:https://stackoverflow.com/questions/46202300/retrofit-rxjava-takes-long-time-to-invoke-onerror-when-server-connection-faile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!