java – HttpPost被发送到服务器和服务器响应之间的延迟是什么
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – HttpPost被发送到服务器和服务器响应之间的延迟是什么,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7333字,纯文字阅读大概需要11分钟。
内容图文
![java – HttpPost被发送到服务器和服务器响应之间的延迟是什么](/upload/InfoBanner/zyjiaocheng/789/2794801c1ead46f6a073eead64067872.jpg)
我正在将一个zip文件从Java桌面应用程序上传到一个Httpserver(运行Tomcat 7),我正在使用Apache httpClient 4.5.3并且我使用这个包装器解决方案显示一个显示进度的进度条https://github.com/x2on/gradle-hockeyapp-plugin/blob/master/src/main/groovy/de/felixschulze/gradle/util/ProgressHttpEntityWrapper.groovy
因此,在我的代码中,每次调用回调时都会更新进度条
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("email", comment)
.addPart("bin", binaryFile)
.build();
ProgressHttpEntityWrapper.ProgressCallback progressCallback = new ProgressHttpEntityWrapper.ProgressCallback() {
@Override
public void progress(final float progress) {
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
MainWindow.logger.severe("progress:"+progress);
Counters.getUploadSupport().set((int)progress);
SongKong.refreshProgress(CreateAndSendSupportFilesCounters.UPLOAD_SUPPORT_FILES);
}
}
);
}
};
httpPost.setEntity(new ProgressHttpEntityWrapper(reqEntity, progressCallback));
HttpResponse response = httpclient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
MainWindow.logger.severe("HttpResponse:"+response.getStatusLine());
这会报告以百分比形式上传的文件,但报告100%创建和实际从服务器接收http状态之间存在相当大的延迟.
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.19408
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.40069
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.6073
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.81391
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.99768
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.99778
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.99789
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.999794
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:99.9999
07/07/2017 14.23.54:BST:CreateSupportFile$4$1:run:SEVERE: progress:100.0
07/07/2017 14.24.11:BST:CreateSupportFile:sendAsHttpPost:SEVERE: HttpResponse:HTTP/1.1 200 OK
07/07/2017 14.24.11:BST:CreateSupportFile:sendAsHttpPost:SEVERE: Unknown Request
注意不是因为我的tomcat代码做了很多,因为我还没有为这个函数实现tomcat代码所以它只是默认为“未知请求”代码.
protected void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException
{
String createMacUpdateLicense = request.getParameter(RequestParameter.CREATEMACUPDATELICENSE.getName());
if(createMacUpdateLicense!=null)
{
createMacUpdateLicense(response, createMacUpdateLicense);
}
else
{
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
response.getWriter().println("Unknown Request");
response.getWriter().close();
}
}
如何在用户完成时更准确地向用户报告
更新
我现在已经完全实现了服务器端,这增加了差异
@Override
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException
{
String uploadSupportFiles = request.getParameter(RequestParameter.UPLOADSUPPORTFILES.getName());
if(uploadSupportFiles!=null)
{
uploadSupportFiles(request, response, uploadSupportFiles);
}
else
{
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
response.getWriter().println("Unknown Request");
response.getWriter().close();
}
}
private void uploadSupportFiles(HttpServletRequest request, HttpServletResponse response, String email) throws IOException
{
Part filePart;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
try
{
filePart = request.getPart("bin");
String fileName = getSubmittedFileName(filePart);
response.getWriter().println(email+":File:" + fileName);
//Okay now save the zip file somewhere and email notification
File uploads = new File("/home/jthink/songkongsupport");
File supportFile = new File(uploads, email+".zip");
int count =0;
while(supportFile.exists())
{
supportFile = new File(uploads, email+"("+count+").zip");
count++;
}
InputStream input;
input = filePart.getInputStream();
Files.copy(input, supportFile.toPath());
Email.sendAlert("SongKongSupportUploaded:" + supportFile.getName(), "SongKongSupportUploaded:" + supportFile.getName());
response.getWriter().close();
}
catch(ServletException se)
{
response.getWriter().println(email+":"+se.getMessage());
response.getWriter().close();
}
}
解决方法:
假设您的服务器端代码只是将上传的文件写入某处并在最后响应“DONE”之类的内容,这里是一个粗略的时间表:
Bytes written to socket OutputStream
============================|
<--> Buffering |
Bytes sent by TCP stack |
============================
<------> Network latency|
Bytes received by Tomcat
============================
| (Tomcat waits for all data to finish uploading
| before handing it out as "parts" for your code)
| File written to local file on server
| =====
|
| Response "DONE" written by servlet to socket output
| ==
| <---> Network latency
| == Response "DONE" received by client
| |
| |
"100%" for entity wrapper ^ Actual 100% ^
Discrepancy
<----------------------->
"Twilight Zone" : part of discrepancy you cannot do much about.
(progress feedback impossible without using much lower level APIs)
<--------------------->
尺度当然是完全随意的,但它表明有几个因素可以参与这种差异.
您的服务器在收到所有字节后写入文件,但这并没有太大区别.
那么,因素:
>(客户端)Java I / O层和OS网络堆栈之间的缓冲(可能在几个级别)
>网络延迟
>(服务器端)OS网络堆栈和Java I / O层之间的缓冲(可能在多个级别)
>在磁盘上写入(或完成写入)zip文件的时间
>打印响应的时间(可忽略不计)
>网络延迟
>(客户端)阅读响应的时间(可忽略不计)
因此,您可以将这种差异考虑在内,并将“上传完成”步骤调整为总进度的90%,并在获得最终响应时从90跳到100.从0%到90%,用户会看到“正在上传”,有一个很好的进度条移动,然后你显示“正在处理…”,也许有一个悸动,完成后,跳到100%.
这就是许多其他工具所做的.即使我用我的浏览器下载文件,也有一个小的延迟,在文件实际可用之前,下载似乎在“几乎”100%停留一秒钟(或者在我的旧计算机上更多).
如果“twilight zone”时间远远高于进度包装器所感知的上传时间,那么您可能会遇到问题,因此您的问题就是“这种延迟来自何处?” (现在我不知道).在这种情况下,请提供完整的时间安排(并确保客户端和服务器机器的时钟同步).
如果您最终需要更准确/顺利的进度报告,则需要更多参与设置.您可能需要在服务器端使用更多低级API(例如,不使用@MultipartConfig等),以便让您的服务器执行类似于接收数据时写入磁盘的操作(这使得错误处理更加困难),打印一个点来输出和刷新,每写1%的文件写入磁盘(或任何其他类型的进展,只要它在服务器端的实际进度).然后,您的客户端将能够逐步读取该响应,并获得准确的进度报告.您可以避免在客户端进行线程化,可以按顺序执行此操作:
> POST数据,报告进度但缩放到90%(即如果包装说50%,则报告45%)
>完成后,开始从服务器读取输出,报告91%,95%,无论如何,直到100%.
即便如此,我也不确定是否可以显示所有步骤的进度信息(特别是在100%发送和服务器可能发送的第一个字节之间),所以即使极其复杂的设置也没用(它可能很好地停止暂时保持90%,然后立即转到91/92 / … 99/100).
所以在这一点上它可能不值得.如果您在客户端发送的最后一个字节和收到的响应之间确实有17秒的步长,那么其他内容就会关闭.最初我假设它是用于大量文件,但从那以后你说你的文件高达50MB,所以你可能还有别的东西要看.
内容总结
以上是互联网集市为您收集整理的java – HttpPost被发送到服务器和服务器响应之间的延迟是什么全部内容,希望文章能够帮你解决java – HttpPost被发送到服务器和服务器响应之间的延迟是什么所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。