Как я могу увидеть полную внутреннюю работу клиента OkHttp? Тайм-аут сокета для дооснащения закрыт - PullRequest
0 голосов
/ 12 февраля 2020

Здравствуйте, большое спасибо за ваше время, у меня возникла неизвестная проблема с модернизацией, единственное, что у меня есть, это сообщение о закрытии сокета / тайм-аут, поэтому я думаю, что могу помочь мне получить больше информации о том, как работает клиент okhttp и модернизация работает, и, поскольку я понимаю, что сокеты имеют большее отношение к клиентам HTTP, я хотел бы узнать больше о внутренней работе клиента okhttp, поскольку это может привести к решению.

Так что это моя проблема.

У меня возникла проблема с использованием модернизации для получения данных через Post в приложении android, один из моих CallBacks никогда не возвращается с телом ответа хотя другие вызовы в той же веб-службе стабильны и работают нормально. Эта ошибка является довольно случайной, и это происходит только при использовании модификации в приложении android, при использовании почтальона или API в веб-браузере.

Единственный способ, которым я смог последовательно воспроизвести ошибку, это переключить тип сети на эмуляторе android с Full на HSDPA или любой другой тип сети, отличный от полного или LTE.

<blockquote class="imgur-embed-pub" lang="en" data-id="a/8bgCxtr" data-context="false" ><a href="//imgur.com/a/8bgCxtr"></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>

Вот некоторые ответы, которые я получаю от Throwable на вызовы с ошибками

java. net .SocketTimeoutException: сообщение о тайм-ауте: timeout

Я попытался увеличить тайм-аут на клиенте OkHttp, и вместо ошибки тайм-аута я получил Socket Closed. java. net .SocketException: подробное сообщение о закрытом гнезде: закрытое гнездо

Socket Closed

Не более информации об ошибке, чем эти простые строки, поэтому я искал способ получить больше информации и обнаружил, что могу установить перехватчик logg на клиенте OkHttp, чтобы получить больше информации о проблеме, но того, что я получил, было недостаточно, чтобы увидеть возможное решение.

Это лог, который я получаю, когда вызов возвращается правильно:

D / OkHttp: -> POST http://192.168.1.68: 83 / api / Comercios / comer cios

D / OkHttp: Content-Type: application / json; кодировка = UTF-8

* * D один тысяча тридцать шесть / OkHttp: Content-Length: 418
* * D один тысяча тридцать восемь / OkHttp: Разрешение: Канал eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfVXNlck5hbWUiOiJVU0VSX0JPTkFOWkExIiwiX0hhc2giOiI1U1FGQUEiLCJqdGkiOiIzNmNmYTZlOS01ODk3LTQ0NjYtYjA0Mi1kZGVkMDBiZGU5ZDAiLCJleHAiOjE1ODE0ODAxMjUsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODMiLCJhdWQiOiJNeVRlc3RBcGkifQ.9xAkkMxRpUEFMNdQaZvVTYQ IEc -8w22fl_ubIAVaqi4

D / OkHttp: {"anyObjects": {"idGrupo": "00d60025-6fb9-484f-97f0-08d79dfdbf92"}, "cultura": "", "ha sh": "5SQFAA", "token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfVXNlck5hbWUiOiJVU0VSX0JPTkFOWkExIiwiX0hhc2giOiI1U1FGQUEiLCJqdGkiOiIzNmNmYTZlOS01ODk3LTQ0NjYtYjA0Mi1kZGVkMDBiZGU5ZDAiLCJleHAiOjE1ODE0ODAxMjUsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODMiLCJhdWQiOiJNeVRlc3RBcGkifQ.9xAkkMxRpUEFMNdQaZvVTYQ IE* * -8w22fl_ubIAVaqi4 тысяча сто тридцать два", "Новичок": "USER_BONANZA1"}

* * +1042 Д / OkHttp: -> КОНЕЦ POST (418 байт тело) * * * тысяча сорок три 1044 * D / OkHttp: <- 200 OK <a href="http://192.168.1.68:83/api/Comercios/comercios" rel="nofollow noreferrer">http://192.168.1.68: 83 / API / Comercios / Comer cios
(66ms)

D / OkHttp: кодирование передачи: chunked

D / OkHttp: Тип содержимого: application / json; charset = utf-8

D / OkHttp: сервер: Kestrel

D / OkHttp: X-Powered-By: ASP. NET

D / OkHttp : Дата: среда, 12 февраля 2020 г. 01:03:01 GMT

https://pastebin.com/wRwnMrsk 2020-02-11 19: 02: 59.515

D / OkHttp: < - END HTTP (276837-байтовое тело)

Тело ответа находится в корзине для вставки, слишком долго, чтобы быть в этом сообщении.

, и это когда вызов получает тайм-аут или розетка закрыта

D / OkHttp: -> POST http://192.168.1.68: 83 / API / Comercios / Comer cios D / OkHttp: Тип контента: приложение / JSON; charset = UTF-8 D / OkHttp: Content-Length: 418 D / OkHttp: Авторизация: Носитель EjJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJfVXNlck5hbWUiOiJVU0VSX0JPTkFOWkExIiwiX0hhc2giOiJCRFo1R0EiLCJqdGkiOiI0NmI0MTA0NC03M2M2LTQ5MDEtOTcyMy0yZjE1NjE1ODgzZDgiLCJleHAiOjE1ODE0ODAzMjMsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODMiLCJhdWQiOiJNeVRlc3RBcGkifQ.EgVFlAzqOlV-RpjRRxXpQzp3q3kk1FqTcoaGDQBY0XA * ​​1076 *

D / OkHttp: { "anyObjects": { "idGrupo": "00d60025-6fb9-484f-97f0-08d79dfdbf92"}, "CULTURA": "", "га sh ":" BDZ5GA», "маркер": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfVXNlck5hbWUiOiJVU0VSX0JPTkFOWkExIiwiX0hhc2giOiJCRFo1R0EiLCJqdGkiOiI0NmI0MTA0NC03M2M2LTQ5MDEtOTcyMy0yZjE1NjE1ODgzZDgiLCJleHAiOjE1ODE0ODAzMjMsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODMiLCJhdWQiOiJNeVRlc3RBcGkifQ.EgVFlAzqOlV-RpjRRxXpQzp3q3kk1FqTcoaGDQBY0XA", "Новичок": "USER_BONANZA1"} * * * тысяча семьдесят восемь 1079 * D / OkHttp: -> КОНЕЦ POST (418 байт тела)

D / OkHttp: <- 200 OK <a href="http://192.168.1.68:83/api/Comercios/comercios" rel="nofollow noreferrer">http://192.168.1.68: 83 / api / Comercios / comer cios (34ms)

D / OkHttp: Кодирование передачи: chunked

D / OkHttp: Content-Type: application / json; charset = utf-8

D / OkHttp: сервер: Kestrel

D / OkHttp: X-Powered-By: ASP. NET

D / OkHttp : Дата: среда, 12 февраля 2020 г. 01:05:45 GMT

Он просто возвращает пустое тело без объяснения причин.

При поиске ошибки закрытия сокета или тайм-аут, это были в основном тупики, говоря, что это связано с сервером, а не с приложением, я говорил с человеком, который управляет API и сервером, и снова и снова мне говорили, что с их стороны В этом нет ничего плохого, по крайней мере, что они знают. Одна вещь, которую они упоминают, это то, что, возможно, размер байта тела слишком велик, и поэтому не позволяет закрывать сокет случайным образом, но я не знаю, как сохранить его открытым или если это проблема в первую очередь.

Итак, я хотел бы знать, есть ли способ увидеть более подробный журнал того, что происходит с сервером Okhttp, чтобы я мог лучше найти возможное решение.

Я собираюсь чтобы разместить мой код здесь, модель, которую я отправляю на веб-сервис, хороша, но это не проблема, потому что если структура не соответствует ожиданиям серверов, я получаю ответ onSuccess с подробной ошибкой того, что я сделал неправильно с сервера, это просто когда все в порядке, я получаю тайм-аут или сокет закрыт, плюс, иногда он работает, иногда он не работает (не проблема с сервером, по мнению почтальона и моих коллег), но это никогда не работает, когда я переключаю тип сети на эмуляторе android, и я уже показывал в этом посте.

Это мои реализации Gradle


implementation "com.squareup.retrofit2:retrofit:2.5.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'

Так я собираю свой клиент и модернизирую


private fun buildRetrofit(): Retrofit {

    val logger = HttpLoggingInterceptor()
    logger.setLevel(HttpLoggingInterceptor.Level.BODY)

    val client = OkHttpClient()
        .newBuilder()
        .addInterceptor(logger)
        .build()

    return Retrofit.Builder()
        .baseUrl(FN.returnWebAPI(this))
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

}

Вот так я и делаю вызов, теперь просто получаю тело ответа, чтобы убедиться, что оно не связано с анализом данных. * 11 14 *


val idGrupoComercios = hashMapOf("idGrupo" to id)
                val hashComercio = HashComercio(hash, upperU.usuario.toUpperCase(Locale.getDefault()), "", jwt.toString(), idGrupoComercios
                )
            val callComercios: Call<ResponseBody> =
                service.getComercios(tokenBearer, hashComercio)

            callComercios.enqueue(object :
                Callback<ResponseBody> {
                override fun onFailure(
                    call: Call<ResponseBody>,
                    t: Throwable
                ) {
                    Crashlytics.logException(t)

                }

                override fun onResponse(
                    call: Call<ResponseBody>,
                    response: Response<ResponseBody>
                ) {
                    if (response.code() == 200) {
                       val data = response.body()!!

                }

            })

Так что любая помощь или идеи относительно того, что я могу сделать, будут очень полезны, я нахожусь в положении, когда кажется, что я могу сделать что-то со стороны приложения проекта, поэтому любая помощь было бы здорово.

1 Ответ

0 голосов
/ 13 февраля 2020

Нам удалось найти своего рода выход к проблеме. В прошлом максимальное время ожидания, которое я пробовал, составляло 5 минут при сборке клиента, но похоже, что сокет, который он собирает, закрывается, если вы не максимизируете его, поэтому я изменил тайм-аут на один день, чтобы он максимизировал тайм-аут это может занять.

И система android или сервер на самом деле не собираются ждать ответ в течение дня, поэтому, по большей части, он доставляет ответ, если сервер не сбрасывает connection.

java. net .SocketException: сброс подключения

В этих случаях вы просто устанавливаете true для retryOnConnectionFailure, и даже если для возврата ответа требуется больше времени доставит один.

Я разговаривал с человеком, который управляет серверами, и сказал мне, что проблема в том, что клиенту HTTP или модернизации не удается восстановить сообщение с первой попытки, а последующие попытки с большей вероятностью потерпят неудачу если тело ответа слишком длинное с использованием соединения 3g, также если оно содержит изображения или значения ha sh внутри json, как я делал добавив га sh для полного изображения на json.

Это код для клиента

val client = OkHttpClient.Builder()
            .connectTimeout(1, TimeUnit.DAYS)
            .readTimeout(1, TimeUnit.DAYS)
            .writeTimeout(1, TimeUnit.DAYS)
            .retryOnConnectionFailure(false)
            .callTimeout(1, TimeUnit.DAYS)
            .hostnameVerifier(HostnameVerifier { hostname, session -> true })
            .build()

Также он сказал мне, что для достижения наилучших результатов json при использование HSDPA должно быть меньше 1024 байтов с заголовком и всем. до 2024 байт Ответные тела.

...