当服务器连接失败时,Retrofit + Rxjava 需要很长时间才能调用 onError [英] Retrofit + Rxjava takes long time to invoke onError when server connection failed

查看:140
本文介绍了当服务器连接失败时,Retrofit + Rxjava 需要很长时间才能调用 onError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Retrofit + Rxjava 从服务器获取实体列表,根据我的设计,当任务失败时,首先检查 Internet 连接,然后在 doOnError 方法中检查与服务器的连接可观察.

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.

当客户端未连接到 Internet 时 doOnError 在合理的时间内被调用并且用户收到错误消息但问题是当 Internet 连接时我得到错误的端口或域(检查服务器问题错误)需要很长时间(大约 1 分钟或更长时间),而且真的很烦人.我怎样才能减少这个时间,原因是什么?

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?

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;
    }
}

我如何尝试获取实体列表:

    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();
                }
            });

doOnlineTask 是如何实现的

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 只是一个抽象类

onlineTask is just an abstract class

abstract public void doWhenOnline();

public void doWhenInternetFaild() {
   //implemented somehow
}


public void doWhenServerFaild() {
   //implemented somehow
}

我尝试了什么:

我猜是超时问题,所以我用 OkHttpClient 更改了 Retrofit 超时,但它不起作用.我还更改了自己设置的超时时间并减少了它们.不工作.

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.

推荐答案

我假设您正在使用 OkHttp 客户端来配合 Retrofit.您正在寻找的很可能是连接超时.

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();

这篇关于当服务器连接失败时,Retrofit + Rxjava 需要很长时间才能调用 onError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆