Met OkHttp
-bibliotheek wordt de toepassing geconfronteerd met het volgende probleem met SocketTimeoutException
. Als de verzoekgrootte kleiner is, werkt het prima (minder dan 1 MB). Ik krijg deze uitzondering binnen 10 seconden, zelfs mijn socket time-out (readTimeout
) waarde is veel hoger. Het faalt consequent voor een verzoek (grootte is 1,8 MB). Toen ik een verzoek uitvoerde met HttpUrlConnection
werkte het prima. Wat zou een mogelijke reden van mislukking kunnen zijn?
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: java.net.SocketTimeoutException: timeout
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.Okio$3.newTimeoutException(Okio.java:207)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.AsyncTimeout.exit(AsyncTimeout.java:261)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.AsyncTimeout$1.write(AsyncTimeout.java:158)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.RealBufferedSink.write(RealBufferedSink.java:46)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.internal.http.Http1xStream$FixedLengthSink.write(Http1xStream.java:286)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okio.RealBufferedSink.write(RealBufferedSink.java:96)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.RequestBody$2.writeTo(RequestBody.java:96)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:704)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.RealCall.getResponse(RealCall.java:241)
03-29 12:16:38.997 32066-4018/com.mobile W/System.err: at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at okhttp3.RealCall.execute(RealCall.java:57)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at com.mobizio.api.BaseApi.sendOkHttpRequest(BaseApi.java:81)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at com.mobizio.api.BaseApi.doInBackground(BaseApi.java:45)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at com.mobizio.api.BaseApi.doInBackground(BaseApi.java:30)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:292)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at java.lang.Thread.run(Thread.java:818)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: Caused by: java.net.SocketException: socket is closed
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:759)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at okio.Okio$1.write(Okio.java:80)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
03-29 12:16:38.998 32066-4018/com.mobile W/System.err: ... 20 more
Antwoord 1, autoriteit 100%
Voor OkHttp 3 is de standaardwaarde voor OkHttp 10 seconden. U kunt de time-out verhogen tot 30 seconden.
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(30, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(30, TimeUnit.SECONDS); // socket timeout
Antwoord 2, autoriteit 85%
Ik heb dat probleem opgelost door writeTimeout()
te verhogen.
Probeer:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES); // read timeout
okHttpClient = builder.build();
Antwoord 3, autoriteit 30%
dit heeft mijn probleem opgelost:
OkHttpClient innerClient = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES) // read timeout
.build();
Antwoord 4, autoriteit 10%
Gebruik dit voor Kotlin
val client1 = OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES) // write timeout
.readTimeout(2, TimeUnit.MINUTES) // read timeout
.addInterceptor(
BasicAuthInterceptor(
AmvaccAppConstants.AUTHENTICATE_USER_NAME, AmvaccAppConstants.AUTHENTICATE_USER_PASSWORD
)
)
.addInterceptor(interceptor)
.build()
Antwoord 5, autoriteit 7%
Je moet begrijpen dat alleen het toevoegen van dit je probleem niet oplost:
OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
Als je Kotlin + Retrofit + Coroutinesgebruikt, gebruik dan gewoon try
en catch
voor netwerkbewerkingen zoals,
viewModelScope.launch(Dispatchers.IO) {
try {
val userListResponseModel = apiEndPointsInterface.usersList()
returnusersList(userListResponseModel)
} catch (e: Exception) {
e.printStackTrace()
}
}
Waar, Uitzondering is het type kotlin
en niet van java.lang
Dit behandelt elke uitzondering zoals,
- HttpException
- SocketTimeoutException
- FATAL UITZONDERING: DefaultDispatcher etc
Hier is mijn functie usersList()
@GET(AppConstants.APIEndPoints.HOME_CONTENT)
suspend fun usersList(): UserListResponseModel
Antwoord 6
If you are using Retrofit and Kotlin then use following code:
var BASE_URL:String="Your URL"
val clientSetup = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES) // write timeout
.readTimeout(1, TimeUnit.MINUTES) // read timeout
.build()
val getClientApi: ApiInterface
get() {
var retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(clientSetup)
.build()
}
Antwoord 7
Run in een ren vangen
runCatching {
service
}
.map {
if (it.isSuccessful && it.body() != null) {
Success(Unit)
} else {
Error(Failure.AuthError.error(it.errorBody()))
}
}
.getOrElse {
Error(Failure.Throwable(it))
}
Antwoord 8
In mijn geval helpt het toevoegen van ping intervalaan OkHttp veel bij het verminderen van het aantal SocketTimeoutExceptionsin de app.
OkHttpClient.Builder()
.pingInterval(3, SECONDS)
.build()
maar ik weet niet zeker of deze time-outs verband hielden met de grootte van het verzoek.
Ik heb het ook genoemd in dit probleem op githubgemeld aan OkHttp-bibliotheek
Antwoord 9
Controleer of uw url correct is. Deze fout kan het gevolg zijn van een verkeerde url-regel