问题描述
- 请问大家,浏览器关闭动态网页,服务器端能侦听到 吗 ?
-
场景一:浏览器关闭网页,服务器端能知道 吗?
场景二:android客户端下载页面或文件,然后取消下载,服务器端能知道 吗 ?我用java代码中的 HttpClient 和 HttpURLConnection 模拟测试,关闭连接
httpclient.getConnectionManager().shutdown(); 和 httpUrlConnection.disconnect(); 后 服务器端都是不知道的
请问大家, 是确实服务器端侦测不到,还是我方法不对?
解决方案
HTTP协议是无状态协议。
无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,也不会因为加入cookies、session机制而变成有状态的。要明白,这种前后因果关系:“我们要实现的是一种web应用,实现这种应用的协议我们选择了http这种本质上是无状态的通信协议。但是事实上,我们需要我们的web应用是有状态的。所以我们加入了cookies、session等机制去实现由状态的web应用”。所以我们可以这么理解:
Web应用=http协议+session、cookies等状态机制+其他辅助的机制。
如果想知道客户端是否关闭,需要客户端想服务器端报告,比如通过jsJS监听关闭浏览器事件之Onunload与Onbeforeunload,当然,可能还有其他方法
解决方案二:
场景一:浏览器关闭网页,服务器端能知道 吗?
服务器不知道
场景二:android客户端下载页面或文件,然后取消下载,服务器端能知道 吗 ?
这就看你下载文件采用什么方式,如果你在下载的时候服务器监听下载流的话,服务器可以知道是否取消下载。否则不知道!
解决方案三:
如果当前会话尚未结束,是可以侦听到的
否则不可以
解决方案四:
你需要的是长连接,普通的http请求服务器响应后就断开了,关闭浏览器服务端不可能知道的,看看tomcat的comet
解决方案五:
对于场景二:
String fileName = fileInfo.getOriginalName();
String nowPath = PropertyUtil.get("root_dir") + fileInfo.getFilePath();
response.setContentType("application/x-download");
InputStream in = null;
OutputStream out = null;
try {
// 以流的形式下载文件
in = new BufferedInputStream(new FileInputStream(nowPath));
out = new BufferedOutputStream(response.getOutputStream());
byte[] b = new byte[1024];
int i = 0;
while ((i = in.read(b)) > 0) {
out.write(b, 0, i);
}
out.flush();
// out.close();
fileDevice.setFileStatus(FileConstant.FILE_STATUS_DOWNLOAD);
this.fileDeviceRelationService.updateFileDeviceRelationByCondition(fileDevice);
} catch (Exception e) {
logger.debug("/content/download_contents error by " + e.getMessage(), e.getCause());
httpStatus = org.springframework.http.HttpStatus.NOT_FOUND;
return new ResponseEntity<Map<String, Object>>(map, httpStatus);
} finally {
if (in != null) {
in.close();
in = null;
}
if (out != null) {
out.close();
out = null;
}
}
return new ResponseEntity(httpStatus);
以上是程序代码,设计的初衷是:
Android客户端在下载文件的时候,如有没有此文件,就告诉客户端,此文件未找到,如果有此文件,就将文件流response给android客户端。
Android客户端正在下载文件的时候,如果客户端取消下载(会调用httpclient.getConnectionManager().shutdown();),那么服务器端能catch到 连接被中断的 IO异常,可实际情况是,服务器根本不知道连接被中断,因此无法知道 客户端取消下载了。
我的理解是,这种文件下载,通过流传输,也是建立一种tcp连接,按道理,在传输的过程中,一端关闭,另一端是知道的。
到底是我理解的有问题,还是 程序写的有问题呢?