I am trying to POST request to server for fetch data but sometime It's occure SocketTimeoutException
!
I used Ok3Client
to resolve it but I facing the same Exception How can I resolve it?
My code is below
public void getNormalLogin() {
if (mProgressDialog == null) {
mProgressDialog = ViewUtils.createProgressDialog(mActivity);
mProgressDialog.show();
} else {
mProgressDialog.show();
}
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
restadapter = new RestAdapter.Builder().setEndpoint(HOST).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new Ok3Client(new OkHttpClient())).build();
mApi = restadapter.create(Api.class);
mApi.SignIn(etEmail.getText().toString(), etPassword.getText().toString(), new Callback<ArrayList<SignUpMainBean>>() {
@Override
public void success(ArrayList<SignUpMainBean> signUpMainBeen, Response response) {
mProgressDialog.dismiss();
LOGD("Status:: ::", String.valueOf(response.getStatus()));
LOGD("Code:: ::", String.valueOf(signUpMainBeen.get(0).getCode()));
if (signUpMainBeen != null && signUpMainBeen.size() > 0) {
if (signUpMainBeen.get(0).getCode() == 1) {
for (int i = 0; i < signUpMainBeen.size(); i++) {
for (int j = 0; j < signUpMainBeen.get(i).getResult().size(); j++) {
showToast(mActivity, getString(R.string.you_have_successfully_login), Toast.LENGTH_SHORT);
LOGD("Success", "Success");
finish();
SignIn.mActivity.finish();
}
}
} else if (signUpMainBeen.get(0).getCode() == 0) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.invalid_email_password), Toast.LENGTH_SHORT);
LOGD("Invalid email or password", "Invalid email or password");
} else if (signUpMainBeen.get(0).getCode() == -1) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.your_account_is_inactive), Toast.LENGTH_SHORT);
LOGD("Your account is inactive", "Your account is inactive");
}
}
}
@Override
public void failure(RetrofitError error) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.can_not_connect_to_server), Toast.LENGTH_SHORT);
LOGD("Failure", "Failure");
}
});
}
}
My Error Log is
D/Retrofit: java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:532)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:40)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:255)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:185)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:126)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
at okhttp3.RealCall.getResponse(RealCall.java:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.execute(RealCall.java:57)
at com.jakewharton.retrofit.Ok3Client.execute(Ok3Client.java:40)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Increase the time if the fetching is taking more time use this code it worked for me
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100,TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("yourbaseurl").client(client)
.addConverterFactory(GsonConverterFactory.create(new Gson())).build();
hay this is work around not the best practice this comments down Back end should not take this long and user must be notified with error or try again message
Preventing SocketTimeoutException
is beyond our limit...One way to effectively handle it is to define a connection timeout
Example for
retrofit 1.9.0
restadapter = new RestAdapter.Builder().setEndpoint(HOST).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new OkHttpClient()
.setReadTimeout(30, TimeUnit.SECONDS)
.setConnectTimeout(30, TimeUnit.SECONDS)).build();
retrofit 2.0.0
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setReadTimeout(30, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
retrofit 2.4.0
// setting custom timeouts
OkHttpClient.Builder client = new Builder();
client.connectTimeout(15, TimeUnit.SECONDS);
client.readTimeout(15, TimeUnit.SECONDS);
client.writeTimeout(15, TimeUnit.SECONDS);
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
}
return retrofit;
}
A possible resolution for this is make sure that you sending the correct request body to the server. For example, does the server need x-www-form-urlencoded
or form-data
in its request body? A simple way to test this is using Postman.
来源:https://stackoverflow.com/questions/39219094/sockettimeoutexception-in-retrofit