我发现了一种奇怪的hack-y方法来修复我的代码,我想知道是否有人可以解释它为什么起作用。我正在编写与REST API通信的代码,以上传拆分为多个HTTP请求的视频文件。
我的视频部分之一请求连接时遇到问题,但从未响应。该程序将视频分为五个部分上传,但始终会挂在这五个部分的第三部分上。我决定添加一个请求硬超时,以强制程序跳过该挂起的部分。好吧,神奇的是添加了该计时器之后,就不再有挂断电话了!
有任何想法为什么会这样吗?该请求实际上并没有超时,但是此代码的添加使我的程序不断变化。
private void uploadParts(String assetId) throws IOException {
//set up post request
HttpClient client = HttpClientBuilder.create().build();
String url = "";
//prepare video
File video = new File("files/video.mp4");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(video));
int partMaxSize = 1024 * 1024 * 5;
byte[] buffer = new byte[partMaxSize];
double fileSize = video.length();
System.out.println(fileSize);
System.out.println(fileSize / partMaxSize);
int parts = (int) Math.ceil(fileSize / partMaxSize);
System.out.println(parts);
for(int i = 1; i < parts+1; i++) {
String partNumber = i + "";
System.out.println("part: " + partNumber);
int partSize = (int) (i < parts ? partMaxSize : fileSize);
fileSize -= partSize;
int tmp = 0;
tmp = bis.read(buffer);
url = String.format("https://www.site.com/upload/multipart/%s/%s", assetId, partNumber);
final HttpPut request = new HttpPut(url);
request.addHeader("Authorization", "Bearer " + accessToken);
request.addHeader("Content-Type", "application/octet-stream");
request.setEntity(new ByteArrayEntity(buffer));
//Magical code start
int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
@Override
public void run() {
if (request != null) {
request.abort();
}
}
};
new Timer(true).schedule(task, hardTimeout * 1000);
//Magical code end
HttpResponse response = client.execute(request);
System.out.println(response.getStatusLine().getReasonPhrase());
}
bis.close();
}
如果我省略了神奇的代码部分,我的代码将挂在第三部分。如果我将其包含在内,则程序运行正常。
我找到了答案!原来HttpClient一次只允许一定数量的连接。根据我的代码,默认的最大连接数为2。我需要在每个连接完成并且上载运行良好之后关闭每个连接。
固定代码添加了请求连接释放。
private void uploadParts(String assetId) throws IOException {
//set up post request
HttpClient client = HttpClientBuilder.create().build();
String url = "";
//prepare video
File video = new File("files/video.mp4");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(video));
int partMaxSize = 1024 * 1024 * 5;
byte[] buffer = new byte[partMaxSize];
double fileSize = video.length();
System.out.println(fileSize);
System.out.println(fileSize / partMaxSize);
int parts = (int) Math.ceil(fileSize / partMaxSize);
System.out.println(parts);
for(int i = 1; i < parts+1; i++) {
String partNumber = i + "";
System.out.println("part: " + partNumber);
int partSize = (int) (i < parts ? partMaxSize : fileSize);
fileSize -= partSize;
int tmp = 0;
tmp = bis.read(buffer);
url = String.format("https://www.site.com/upload/multipart/%s/%s", assetId, partNumber);
final HttpPut request = new HttpPut(url);
request.addHeader("Authorization", "Bearer " + accessToken);
request.addHeader("Content-Type", "application/octet-stream");
request.setEntity(new ByteArrayEntity(buffer));
//Magical code start
int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
@Override
public void run() {
if (request != null) {
request.abort();
}
}
};
new Timer(true).schedule(task, hardTimeout * 1000);
//Magical code end
HttpResponse response = client.execute(request);
request.releaseConnection();
System.out.println(response.getStatusLine().getReasonPhrase());
}
bis.close();
}
计时器正在工作,因为它在10秒后关闭了我的旧连接。伙计们,谢谢您的投入。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句