一、在使用fiddler抓包工具会出现如下场景
二、keep-alive 保持连接
"Connection: keep-alive" 是 HTTP 协议中的一个头部字段,用于指示客户端和服务器之间的连接是否保持活跃状态。
当客户端发送一个 HTTP 请求给服务器时,可以在请求头部中包含 "Connection: keep-alive" 字段,这表示客户端希望与服务器保持持久连接。这意味着一旦服务器响应完请求后,连接不会立即关闭,而是会保持打开状态一段时间,以便后续可能发送的请求可以在同一连接上进行。这样可以减少因频繁建立和关闭连接而产生的性能开销。
即使请求头部中包含了 "Connection: keep-alive" 字段,服务器也可以选择在响应中关闭连接,或者在一定时间后自动关闭连接。但通常情况下,如果客户端和服务器都支持持久连接,并且请求头部中包含了 "Connection: keep-alive" 字段,那么连接就会保持活跃状态一段时间,以便后续的请求可以复用这个连接。
三、实现 请求头关闭保持(客户端)
3.1使用 Python
的 requests 库发送 HTTP 请求,你可以通过以下方式设置:
import requests
headers = {'Connection': 'close'}
response = requests.get('http://example.com', headers=headers)
3.2使用 jQuery 的 AJAX 方法发送请求
$.ajax({
url: 'http://example.com',
method: 'GET',
headers: {'Connection': 'close'},
success: function(response) {
// 请求成功时的处理逻辑
console.log('请求成功:', response);
},
error: function(xhr, status, error) {
// 请求失败时的处理逻辑
console.error('请求失败:', status, error);
}
});
3.3当不写 connection,客户端默认会保持请求连接
当客户端不显式设置 "Connection" 头部时,默认情况下,大多数现代的 HTTP 客户端会采用持久连接(keep-alive)的方式来发送请求。这意味着客户端会尝试在请求完成后保持连接打开状态,以便在同一连接上发送后续的请求。
持久连接可以提高性能,因为它减少了因频繁建立和关闭连接而带来的开销。然而,并非所有的服务器都支持持久连接,也不是所有的客户端都会使用它。因此,服务器可能会在响应完成后关闭连接,或者客户端可能会选择在每个请求后关闭连接,这取决于具体的实现和配置。
四、服务器配置
Java Servlet 中,你可以通过设置响应头部来控制连接的保持和关闭。具体地说,你可以在 Servlet 中使用 HttpServletResponse 对象来设置响应头部。
要配置持久连接(keep-alive),你可以在 Servlet 的 doGet() 或 doPost() 方法中添加如下代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应头部,指示客户端保持连接
response.setHeader("Connection", "keep-alive");
// 其他处理逻辑...
}
要配置关闭连接,在响应完成后,你可以将连接设置为 "close":
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应头部,指示客户端关闭连接
response.setHeader("Connection", "close");
// 其他处理逻辑...
}
当服务器响应json数据后,如果间隔task任务时间再发送json则不需要 二次请求
String respondJson = "{\"status\":\"" + tag + "\"}";
// 设置响应的内容类型为application/json
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
// 获取响应的输出流
PrintWriter out = response.getWriter();
// 将JSON字符串写回客户端
out.println(respondJson);
out.flush();
要定时关闭连接,你可以设置一个特定的超时时间,然后在超时后关闭连接。这可以通过使用 Servlet 的 AsyncContext 和定时器来实现。下面是一个简单的示例代码,演示了如何在一定时间后关闭连接:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Timer;
import java.util.TimerTask;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/example", asyncSupported = true)
public class ExampleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应的内容类型为application/json
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
// 获取响应的输出流
PrintWriter out = response.getWriter();
// 创建异步上下文
final AsyncContext asyncContext = request.startAsync();
// 设置定时器,在一定时间后关闭连接
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 关闭异步上下文
asyncContext.complete();
// 取消定时器
cancel();
}
}, 5000); // 5000毫秒后关闭连接
// 将JSON字符串写回客户端
String respondJson = "{\"status\":\"ok\"}";
out.println(respondJson);
out.flush();
}
}
在这个示例中,我们使用了一个定时器来在一定时间后关闭异步上下文。在 doGet() 方法中,我们首先设置了响应的内容类型,并获取了响应的输出流。然后,我们创建了一个异步上下文对象,并使用定时器在 5000 毫秒后关闭了这个异步上下文,即关闭连接。最后,我们将 JSON 字符串写回客户端。