#android #kotlin #retrofit #retrofit2 #okhttp
#Android #kotlin #модифицированный #retrofit2 #okhttp
Вопрос:
У меня есть клиент, который выполняет n попыток с определенным таймаутом, когда я выполняю тесты в эмуляторе, на каждую попытку всегда уходит 40 секунд или даже больше, время, которое я настроил, составляет 5 секунд.
Я выполнил тест, прокомментировав эти три строки:
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
Ожидая, что он займет время ожидания по умолчанию (10 секунд) иногда результат был правильным (10 секунд), после нескольких выполнений время больше не совпадает.
Также выполните тест на физическом устройстве, и произойдет то же самое.
Есть идеи, что происходит?
object Client {
private const val PATTERN = "0000"
private const val S_TAG = "{SN}"
private const val C_TAG = "{CC}"
/**
* Retrofit Builder is created
* @param sNbr
* @param cCode
* @return Retrofit
*/
private fun createRetrofitBuilder(
sNbr: String,
cCode: String
): Retrofit {
val builder = Retrofit.Builder().baseUrl(
getServer(
sNbr,
cCode))
.client(CertificateValidation.getUnsafeOkHttpClient())
.addConverterFactory(SimpleXmlConverterFactory.create())
return builder.build()
}
/**
* Gets URL of request.
* @param sNbr
* @param cCode
* @return server
*/
private fun getServer(sNbr: String, cCode: String): String {
var server = Constants.URL_SERVICE
server = server.replace(S_TAG,
getStString(
storeNbr
)
)
server = server.replace(C_TAG, countryCode)
return server
}
/**
*
*/
private fun getStString(sNbr: String): String {
val decimalFormat = DecimalFormat(PATTERN)
return decimalFormat.format(sNbr.toInt())
}
/**
* @param serviceType
* @return T
*/
fun <T> buildService(
serviceType: Class<T>,
sNbr: String,
cCode: String
): T {
return createRetrofitBuilder(
sNbr,
cCode
).create(serviceType)
}}
CertificateValidation.kt
class CertificateValidation {
companion object {
private const val TIMEOUT: Long = 5
/**
* Method that validates the SSL certificate sent from the Service.
*/
fun getUnsafeOkHttpClient(): OkHttpClient {
// Create a trust manager that does not validate certificate chains
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
@Throws(CertificateException::class)
override fun checkClientTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {
}
@SuppressLint("TrustAllX509TrustManager")
@Throws(CertificateException::class)
override fun checkServerTrusted(
chain: Array<java.security.cert.X509Certificate>,
authType: String
) {
}
override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> {
return arrayOf()
}
})
// Install the all-trusting trust manager
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory = sslContext.socketFactory
val builder = OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.connectionSpecs(
listOf(
ConnectionSpec.COMPATIBLE_TLS,
ConnectionSpec.CLEARTEXT
)
)
builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
return builder.build()
}
}}
Ответ №1:
Вы должны прочитать https://www.baeldung.com/okhttp-timeouts
Скорее всего, вы хотите использовать callTimeout для управления одним таймаутом для всего вызова. При повторном использовании соединения тайм-ауты подключения, чтения и записи часто не срабатывают из-за других запросов в том же базовом сокете ввода-вывода.
OkHttpClient client = new OkHttpClient.Builder()
.callTimeout(10, TimeUnit.SECONDS)
.build();
Кроме того, прослушиватель событий часто дает вам лучшее представление о том, что перехватчик запросов https://square.github.io/okhttp/events /