我成功上传了较小的文件< 10MB通过okhttp(3.8.1)通过https。
使用以下库:
但是如果我尝试使用100-200MB左右的相同代码,则上传失败并显示异常:
javax.net.ssl.SSLException: Write error: ssl=0x559a6311d0: I/O error during system call, Connection reset by peer
at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:771)
at okio.Okio$1.write(Okio.java:79)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:180)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
at okio.RealBufferedSink.write(RealBufferedSink.java:41)
at okhttp3.internal.http1.Http1Codec$ChunkedSink.write(Http1Codec.java:325)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
at okio.RealBufferedSink.write(RealBufferedSink.java:91)
at de.fhdo.gobsis.mobile.libraries.ProgressRequestBody.writeTo(ProgressRequestBody.java:73)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:62)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
at okhttp3.RealCall.execute(RealCall.java:69)
at com.example.services.Uploadervice.onHandleIntent(UploadCaseService.java:274)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
设备正在运行且应用程序处于前台。 我在Android IntentService中使用以下代码:
ProgressRequestBody body = new ProgressRequestBody(
getApplicationContext(),
new ProgressRequestBody.UploadInfo(Uri.fromFile(json), json.length()),
new ProgressRequestBody.ProgressCallback() {
@Override
public void onProgress(long progress, long total) {
publishProgress(progress, total);
}
});
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.MINUTES)
.writeTimeout(10, TimeUnit.MINUTES)
.readTimeout(10, TimeUnit.MINUTES)
.build();
Request request = new Request.Builder()
.header("X-Client-Type", "Android")
.addHeader("APIKEY", "SomeRND")
.url(url)
.post(body)
.build();
//Exception occures here:
Response response = client.newCall(request).execute();
ProgressRequestBody扩展了默认的okhttp RequestBody添加了一个用于报告当前uploadprogress的接口。 我覆盖了 writeTo(BufferedSink接收器) - 方法如下:
@Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = mUploadInfo.contentLength;
byte[] buffer = new byte[65536];
InputStream in = in();
long uploaded = 0;
try {
int read;
while((read = in.read(buffer)) != -1) {
mListener.onProgress(uploaded, fileLength);
uploaded += read;
sink.write(buffer, 0, read);
}
} finally {
in.close();
}
}
通过 in() -method
读取文件 private InputStream in() throws IOException {
InputStream stream = null;
try {
stream = getContentResolver().openInputStream(mUploadInfo.contentUri);
} catch (Exception ex) {
Log.e(LOG_TAG, "Error getting input stream for upload", ex);
}
return stream;
}
大约3-5分钟后上传失败。有人能告诉我如何获得稳定的连接或在它破碎后恢复吗?在几篇文章中,我读到ssl异常发生在大文件上传时并不罕见,但我发现没有令人满意的解决方案如何解决这个问题。