#android #tcp #socket.io #httpurlconnection #okhttp
#Android #tcp #socket.io #httpurlconnection #okhttp
Вопрос:
Мой API приложения ведет себя странно. Ожидаемое время отклика одного из API моего приложения Live от 2 до 3 секунд, но для ответа требуется много времени!
Тестовые примеры:
- Работает с WIFI = Да
- Работает с оператором Airtel = Да
- Работает с оператором Jio = Да
- Работает в сети других стран = Да
- Работает в мобильном браузере с оператором Vodafone Idea = Да
- Работает с тем же API, что и приложение для IOS, используя оператора Vodafone Idea = Да
Основная проблема: проблема с оператором Vodafone Idea, использующим приложение = очень медленно
Случай 1.
URL url = new URL("https://example.com");
urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(10000);
int code = urlConnection.getResponseCode();
if (code != 200) {
throw new IOException("Invalid response from server: " code);
}
BufferedReader rd = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
Log.e("data", line);
}
Результат:
- Первый раз от 40 до 50 секунд.
- При каждом следующем последовательном вызове он будет возвращаться в течение 2-5 секунд в соответствии с ожиданиями.
Случай 2:
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request.Builder requestBuilder = new Request.Builder()
.url("https://example.com")
.addHeader("Content-Type", "application/json");
Request request = requestBuilder.build();
Log.e("APi", "REQUEST: " request.toString());
Call call1 = okHttpClient.newCall(request);
call1.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e("APi", "APi Failed");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
Log.e("APi", "APi isSuccessful:" response.isSuccessful());
Log.e("APi", "Response:" response.body().string());
}
});
Результат:
- Каждый раз занимает от 40 до 50 секунд.
Случай 3:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS).build();
Request.Builder requestBuilder = new Request.Builder()
.url("https://example.com")
.addHeader("Content-Type", "application/json");
Request request = requestBuilder.build();
Log.e("APi", "REQUEST: " request.toString());
Call call1 = okHttpClient.newCall(request);
call1.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e("APi", "APi Failed");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
Log.e("APi", "APi isSuccessful:" response.isSuccessful());
Log.e("APi", "Response:" response.body().string());
}
});
Результат:
- Каждый раз это занимает от 5 до 6 секунд.
Примечание: я боюсь использовать .ConnectTimeout(1, TimeUnit.СЕКУНДЫ) через 1 секунду в приложении он начал давать больше сбоев api и также не выглядит правильным решением.
Обновить CaseStudy:
https://github.com/square/okhttp Подробная отладка OkHttpClient. он выдает ошибку ниже примерно в 4 раза.
failed to connect to xxx.com/2001:4860:4802:36::15 (port XXX) from /2402:3a80:1b8f:ca21:847:21a8:5ffc:fc30 (port XXX) after 10000ms
пакет okhttp3.internal.connection.Класс RealConnection.
пытаюсь установить connectSocket, но получаю ошибку.
-> После добавления «www»www.example.com в мой домен. Изменение времени отклика с 40 секунд до 12 секунд приблизительно для библиотеки okhttp.
Комментарии:
1. Вы должны собрать некоторые события с помощью прослушивателя и добавить их в свой вопрос square.github.io/okhttp/events
2. @YuriSchimke Спасибо. Добавлено исключение во время отладки. Пожалуйста, обратите внимание, что проблема возникает только в 1 конкретной сети!
3. В моем приложении также есть Google Cloud Engine для сервера и использования хранилища firebase и облачных функций @YuriSchimke
4. Интересная проблема, но я боюсь, что мы упускаем полную картину. Может быть, вы создаете действительно много других подключений в своем приложении? Я не думаю, что этот приведенный вами код сможет воспроизвести проблему, которую вы описываете, сам по себе, поэтому создание минимально воспроизводимого примера очень помогло бы.
5. В вашем сообщении указан IPv6-адрес. Используют ли сценарии, которые работают быстрее, IPv4 или IPv6?
Ответ №1:
Трудно увидеть всю картину, потому что вы не объясняете, как вы выполняете последующие подключения. Вполне возможно, что вы повторно используете существующее соединение. По умолчанию HTTP / 1.1 поддерживает активные соединения.
Проверка того, имеет ли значение использование обычного текста HTTP по сравнению с HTTPS, также может быть интересной, поскольку стоимость настройки соединения с HTTPS выше. Ваш клиент также может выполнить дополнительную проверку на основе возвращаемого сертификата.
Если изменение имени хоста имеет такое большое значение, то я бы обязательно посмотрел, как в системе настроен распознаватель имен.
Я бы также зафиксировал сетевой трафик и посмотрел, что занимает много времени. tcpdump — ваш друг, или вы всегда можете рассмотреть возможность использования wireshark
Как предлагали другие, вы также можете отключить стек IPv6 в окне, чтобы исключить источник проблемы.
Комментарии:
1. я посоветовался со своими товарищами по команде, которые обладают хорошими знаниями на сетевом уровне, мы обнаружили, что даже «трассировка маршрута <<Домен>>» в терминале занимает слишком много времени! В заключение. я использовал «HttpsURLConnection» и в первый раз сохраняю setConnectTimeout в течение 1 секунды. для любых других следующих вызовов это будет обычный тайм-аут!
2. трассировка маршрута может вводить в заблуждение, особенно если вы используете имя хоста вместо IP-адреса. Некоторое сетевое оборудование также может блокировать некоторый трафик. Ваш лучший выбор — анализатор сетевого трафика.