简体   繁体   English

利用Apache HttpClient的持久性?

[英]Utilizing persistence with Apache HttpClient?

My goal is to connect to a server and then maintain the connection. 我的目标是连接到服务器,然后维护连接。 The server keeps pushing me some data whenever it has any. 只要有数据,服务器就会不断向我推送一些数据。 I wrote the following but it works only the first time. 我写了以下内容,但仅在第一次使用。 The second time onwards, it gives me an exception saying that the get.getResponseBodyAsStream() is null. 第二次,它给了我一个例外,说get.getResponseBodyAsStream()为null。 I was thinking that Apache's HTTPClient keeps the connection alive by default so what I understand is that I need a blocking call somewhere. 我当时以为Apache的HTTPClient默认情况下会保持连接活动,所以我了解到我需要在某个地方进行阻塞调用。 Can someone help me out here? 有人可以帮我吗?

        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();
        }

Actually at the end of the day, I am trying to get a persistent connection to the server (I will handle possible errors later) so that I can keep receiving updates from my server. 实际上,在一天结束时,我试图与服务器建立持久连接(稍后将处理可能的错误),以便可以继续接收来自服务器的更新。 Any pointers on this would be great. 关于此的任何指示都是很棒的。

I haven't looked in great detail or tested code, but I think repeatedly opening up a reader on the response is probably a bad idea. 我没有详细研究或测试代码,但我认为反复在响应中打开读者可能不是一个好主意。 I'd take and move the input = line up outside the loop, for starters. 对于初学者来说,我将input =对齐并移到循环外。

You cannot do it like this. 你不能这样做。 When you have read the "body" of the response, that is it. 当您阅读了响应的“正文”时,就是这样。 To get more information, the client has to send a new request. 为了获得更多信息,客户端必须发送一个新请求。 That is the way that the HTTP protocol works. 这就是HTTP协议的工作方式。

If you want to stream multiple chunks of data in a single HTTP response, then you are going to need to do the chunking and unchunking yourself. 如果您想在单个HTTP响应中流式传输多个数据块,那么您将需要对数据块进行分块并取消分块。 There a variety of approaches you could use, depending on the nature of the data. 您可以使用多种方法,具体取决于数据的性质。 For example: 例如:

  • If the data is XML or JSON, send a stream of XML documents / JSON objects an have the receiver separate the stream into documents / objects before sending them to the parser. 如果数据是XML或JSON,请发送XML文档/ JSON对象流,并让接收者在将它们发送到解析器之前将流分离为文档/对象。
  • Invent your own light-weight "packetization" where you precede each chunk with a start marker and a byte count. 发明自己的轻量级“打包”,在每个打包之前添加一个开始标记和一个字节数。

The other alternative is to use multiple GET requests, but try to configure things so that the underlying TCP/IP connection stays open between requests; 另一种选择是使用多个GET请求,但尝试进行配置,以使基础TCP / IP连接在请求之间保持打开状态。 see HTTP Persistent Connections . 请参阅HTTP持久连接

EDIT 编辑

Actually, I need to send only one GET request and keep waiting for status messages from the server. 实际上,我只需要发送一个GET请求,并一直等待来自服务器的状态消息。

The HTTP status code is transmitted in the first line of the HTTP response message. HTTP状态代码在HTTP响应消息的第一行中传输。 There can be only one per HTTP response, and (obviously) there can be only one response per HTTP request. 每个HTTP响应只能有一个响应,并且(显然)每个HTTP请求只能有一个响应。 Therefore what you are trying to do is impossible using normal HTTP status codes and request/reply messages. 因此,使用常规的HTTP状态代码和请求/答复消息是不可能的

Please review the alternatives that I suggested above. 请查看我上面建议的替代方法。 The bullet-pointed alternatives can be tweaked to allow you to include some kind of status in each chunk of data. 可以对项目符号指出的替代项进行调整,以使您可以在每个数据块中包括某种状态。 And the last one (sending multiple requests) solves the problem already. 最后一个(发送多个请求)已经解决了问题。

EDIT 2 编辑2

To be more particular, it seems that keeping the connection alive is done transparently 更具体地说,似乎保持连接保持活动是透明进行的

That is correct. 那是对的。

... so all I need is a way to get notified when there is some data present that can be consumed. ...因此,我需要的是一种在存在一些可以使用的数据时得到通知的方法。

Assuming that you are not prepared to send multiple GET requests (which is clearly the simplest solution!!!), then your code might look like this: 假设您不准备发送多个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);
  }

But if you are only sending status codes or if the rest of each data chunk can be shoe-horned onto the same line, you can simplify this further. 但是,如果您仅发送状态代码,或者每个数据块的其余部分都可以插入同一行,则可以进一步简化此过程。

If you are trying to implement this so that your main thread doesn't have to wait (block) on reading from the input stream, then either use NIO, or use a separate thread to read from the input stream. 如果您试图实现此目的,以便您的主线程不必等待(阻止)从输入流中读取,则可以使用NIO,也可以使用单独的线程从输入流中读取。

in my opinion HttpClient library is meant for client pull situations. 我认为HttpClient库用于客户端请求情况。 i recommend you to look at comet which supports server push 我建议您看看支持服务器推送的彗星

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

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