繁体   English   中英

利用Apache HttpClient的持久性?

[英]Utilizing persistence with Apache HttpClient?

我的目标是连接到服务器,然后维护连接。 只要有数据,服务器就会不断向我推送一些数据。 我写了以下内容,但仅在第一次使用。 第二次,它给了我一个例外,说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();
        }

实际上,在一天结束时,我试图与服务器建立持久连接(稍后将处理可能的错误),以便可以继续接收来自服务器的更新。 关于此的任何指示都是很棒的。

我没有详细研究或测试代码,但我认为反复在响应中打开读者可能不是一个好主意。 对于初学者来说,我将input =对齐并移到循环外。

你不能这样做。 当您阅读了响应的“正文”时,就是这样。 为了获得更多信息,客户端必须发送一个新请求。 这就是HTTP协议的工作方式。

如果您想在单个HTTP响应中流式传输多个数据块,那么您将需要对数据块进行分块并取消分块。 您可以使用多种方法,具体取决于数据的性质。 例如:

  • 如果数据是XML或JSON,请发送XML文档/ JSON对象流,并让接收者在将它们发送到解析器之前将流分离为文档/对象。
  • 发明自己的轻量级“打包”,在每个打包之前添加一个开始标记和一个字节数。

另一种选择是使用多个GET请求,但尝试进行配置,以使基础TCP / IP连接在请求之间保持打开状态。 请参阅HTTP持久连接

编辑

实际上,我只需要发送一个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);
  }

但是,如果您仅发送状态代码,或者每个数据块的其余部分都可以插入同一行,则可以进一步简化此过程。

如果您试图实现此目的,以便您的主线程不必等待(阻止)从输入流中读取,则可以使用NIO,也可以使用单独的线程从输入流中读取。

我认为HttpClient库用于客户端请求情况。 我建议您看看支持服务器推送的彗星

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM