使用 OkhttpClient 3.2 和 Retrofit 2 发送视频时出现 java.net.SocketTimeoutException

Posted

技术标签:

【中文标题】使用 OkhttpClient 3.2 和 Retrofit 2 发送视频时出现 java.net.SocketTimeoutException【英文标题】:java.net.SocketTimeoutException when sending video using OkhttpClient 3.2 and Retrofit 2 【发布时间】:2018-04-19 17:36:51 【问题描述】:

我使用 OkhttpClient 使用 OkhttpClient 3.2Retrofit2 将 15 秒长的视频发送到服务器,有时它可以正常工作,但有时我会收到以下错误,这是非常不一致的。

java.net.SocketTimeoutException: 超时

这是我将视频发送到服务器的代码

private void sendVideoToServer( final String videoFilePath,final String api_key)
    
        File videoFile = new File(videoFilePath);
        RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
        MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);

        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() 
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException 
                        okhttp3.Request.Builder ongoing = chain.request().newBuilder();
                        ongoing.addHeader("authorization", api_key);
                        return chain.proceed(ongoing.build());
                    
                )
                .build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(AppConfig.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient)
                .build();

        VideoInterface videoInterface = retrofit.create(VideoInterface.class);
        Call<ResultObject> serverCom = videoInterface.sendVideoToServer(vFile);

        serverCom.enqueue(new Callback<ResultObject>() 
            @Override
            public void onResponse(Call<ResultObject> call, retrofit2.Response<ResultObject> response) 
                ResultObject result = response.body();
                if(!TextUtils.isEmpty(result.getSuccess()))
                    Log.d("video Result " , result.getSuccess());
                
            

            @Override
            public void onFailure(Call<ResultObject> call, Throwable t) 
               Log.d("video error",t.toString());
            
        );
    

阅读了一些问题后,我尝试将连接超时设置为如下所示的 OkhttpClient,但仍然无法解决问题。

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new Interceptor() 
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException 
                        okhttp3.Request.Builder ongoing = chain.request().newBuilder();
                        ongoing.addHeader("authorization", api_key);
                        return chain.proceed(ongoing.build());
                    
                );
builder.connectTimeout(5, TimeUnit.MINUTES)
       .writeTimeout(5, TimeUnit.MINUTES)
       .readTimeout(5, TimeUnit.MINUTES);
OkHttpClient httpClient = builder.build();

我完全不知道这部分做错了什么,请给我一些指导。时长

【问题讨论】:

可能是服务器端或请求参数的问题,请与邮递员联系。你的代码看起来不错 我和邮递员检查过,一切都很好,但是在android中,我用真机测试,它总是超时。 你用邮递员试过大文件吗? 我用邮递员尝试了 4 分钟的视频视频,没问题,但在 android 中,视频超时 15 秒.. ***.com/a/39953566/2587027 如果没有文件名也可以试试这个 【参考方案1】:

尝试传递实际的文件对象

  file = new File(tasks.getImageUrl());
            requestFile =
                    RequestBody.create(MediaType.parse("multipart/form-data"), file);
 body =  MultipartBody.Part.createFormData("file", file.getName(), requestFile);



 sendVideo(body);

【讨论】:

这不是我现在做的?有什么不同?? 您将视频作为 MediaType 传递:RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile); MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody); 啊好吧..让我再试一次【参考方案2】:
OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() 
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException 
                        okhttp3.Request.Builder ongoing = chain.request().newBuilder();
                        ongoing.addHeader("authorization", api_key);
                        return chain.proceed(ongoing.build());
                    
                )
                // Add below line to your okhttp client
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();

【讨论】:

以上是关于使用 OkhttpClient 3.2 和 Retrofit 2 发送视频时出现 java.net.SocketTimeoutException的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio OkHttpClient使用

尝试创建 OkHttpClient 对象时出现 kotlin/TypeCastException

如何使用 okHttpClient 执行 graphql 查询?

OkHttpClient 关闭连接

android OkHttpClient 请求错误

使用 OkHttpClient 时来自 SOCKS 服务器的格式错误的回复