Java 利用Apache HttpClient的持久性?

Java 利用Apache HttpClient的持久性?,java,http,httpclient,Java,Http,Httpclient,我的目标是连接到服务器,然后保持连接。只要服务器有数据,就会不断地向我推送数据。我写了以下内容,但它只在第一次起作用。第二次之后,它给了我一个异常,表示get.getResponseBodyAsStream()为null。我认为Apache的HTTPClient在默认情况下保持连接的活动状态,所以我的理解是我需要在某个地方进行阻塞调用。有人能帮我吗 GetMethod get = new GetMethod(url); String nextLine;

我的目标是连接到服务器,然后保持连接。只要服务器有数据,就会不断地向我推送数据。我写了以下内容,但它只在第一次起作用。第二次之后,它给了我一个异常,表示get.getResponseBodyAsStream()为null。我认为Apache的HTTPClient在默认情况下保持连接的活动状态,所以我的理解是我需要在某个地方进行阻塞调用。有人能帮我吗

        GetMethod get = new GetMethod(url);
        String nextLine;
        String responseBody = "";
        BufferedReader input;

        try {
            httpClient.executeMethod(get);
            while(true) {
                try {
                    input = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));

                    while ((nextLine = input.readLine()) != null)
                        responseBody += nextLine;
                    System.out.println(responseBody);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

实际上,在一天结束时,我正在尝试与服务器建立持久连接(稍后我将处理可能出现的错误),这样我就可以不断从服务器接收更新。任何关于这方面的建议都是很好的。

我还没有详细看过或测试过代码,但我认为反复打开读者对响应的了解可能是个坏主意。首先,我会将
输入=
列移到循环之外。

我没有详细看过或测试过代码,但我认为反复打开响应阅读器可能是个坏主意。首先,我将把
输入=
列移到循环外。

你不能这样做。当您阅读了响应的“主体”时,就是它。要获取更多信息,客户端必须发送新请求。这就是HTTP协议的工作方式

如果您想在一个HTTP响应中流式传输多个数据块,那么您需要自己进行分块和取消分块。根据数据的性质,您可以使用多种方法。例如:

  • 如果数据是XML或JSON,则发送一个XML文档流/JSON对象,并让接收者在将其发送到解析器之前将流分离为文档/对象
  • 发明你自己的轻量级“打包”,在每个块前面加上一个开始标记和一个字节计数
另一种选择是使用多个GET请求,但是尝试配置一些东西,以便在请求之间底层TCP/IP连接保持打开状态;看

编辑

实际上,我只需要发送一个GET请求并一直等待来自服务器的状态消息

HTTP状态代码在HTTP响应消息的第一行中传输。每个HTTP响应只能有一个响应,而且(显然)每个HTTP请求只能有一个响应。因此,您试图使用正常的HTTP状态代码和请求/回复消息来执行的操作是不可能的

请回顾我上面建议的备选方案。可以调整要点替代方案,以允许在每个数据块中包含某种状态。最后一个(发送多个请求)已经解决了这个问题

编辑2


更具体地说,保持连接是透明的

这是正确的

。。。因此,我所需要的只是一种在存在一些可以使用的数据时得到通知的方法

假设您不准备发送多个GET请求(这显然是最简单的解决方案!!!),那么您的代码可能如下所示:

 while (true) {
     String header = input.readLine();  // format "status:linecount"
     if (header == null) {
         break;
     }
     String[] parts = header.split(":");
     String status = parts[0];
     StringBuilder sb = new StringBuilder();
     int lineCount = Integer.parseInt(parts[1]);
     for (int i = 0; i < lineCount; i++) {
         String line = input.readLine();
         if (line == null) {
             throw new Exception("Ooops!");
         }
         sb.append(line).append('\n');
     }
     System.out.println("Got status = " + status + " body = " + body);
  }
while(true){
String header=input.readLine();//格式“status:linecount”
if(头==null){
打破
}
String[]parts=header.split(“:”);
字符串状态=部件[0];
StringBuilder sb=新的StringBuilder();
int lineCount=Integer.parseInt(部分[1]);
对于(int i=0;i
但是,如果您只发送状态代码,或者如果每个数据块的其余部分可以放在同一行上,那么可以进一步简化


如果您试图实现这一点,以便主线程不必等待(阻塞)从输入流读取,那么可以使用NIO,或者使用单独的线程从输入流读取。

您不能这样做。当您阅读了响应的“主体”时,就是它。要获取更多信息,客户端必须发送新请求。这就是HTTP协议的工作方式

如果您想在一个HTTP响应中流式传输多个数据块,那么您需要自己进行分块和取消分块。根据数据的性质,您可以使用多种方法。例如:

  • 如果数据是XML或JSON,则发送一个XML文档流/JSON对象,并让接收者在将其发送到解析器之前将流分离为文档/对象
  • 发明你自己的轻量级“打包”,在每个块前面加上一个开始标记和一个字节计数
另一种选择是使用多个GET请求,但是尝试配置一些东西,以便在请求之间底层TCP/IP连接保持打开状态;看

编辑

实际上,我只需要发送一个GET请求并一直等待来自服务器的状态消息

HTTP状态代码在HTTP响应消息的第一行中传输。每个HTTP响应只能有一个响应,而且(显然)每个HTTP请求只能有一个响应。因此,您试图使用正常的HTTP状态代码和请求/回复消息来执行的操作是不可能的

请回顾我上面建议的备选方案。可以调整要点替代方案,以允许在每个数据块中包含某种状态。最后一个(发送多个请求)已经解决了这个问题

编辑2


更具体地说,保持连接是透明的

那是co