Java 在响应完成之前关闭HttpURLConnection 背景
我在客户端使用HTTP流(服务器推送)情况下的响应。虽然服务器可以通过关闭响应来关闭连接,但客户机也需要能够做到这一点 问题 客户端在单独的线程中处理Java 在响应完成之前关闭HttpURLConnection 背景,java,httpurlconnection,Java,Httpurlconnection,我在客户端使用HTTP流(服务器推送)情况下的响应。虽然服务器可以通过关闭响应来关闭连接,但客户机也需要能够做到这一点 问题 客户端在单独的线程中处理InputStream,如下所示: @Override public void run() { try { for (int b = in.read(); b >= 0; b = in.read()) { char c = (char) b; // Do somethin
InputStream
,如下所示:
@Override
public void run() {
try {
for (int b = in.read(); b >= 0; b = in.read()) {
char c = (char) b;
// Do something with the character
// ...
}
}
catch (IOException e) {
}
}
因此,当我从启动连接的线程调用时(重要的信息是它与处理输入的线程不同),该调用将无限期挂起。我甚至留了一夜,它仍然挂着。甚至打电话也没用
建议?如果服务器未关闭连接但停止发送数据,则.read()中的
将被阻止。现在,请注意HttpURLConnection.HttpInputStream.close()
的代码也将尝试从流中读取,以确定到达流的末尾(。
依次从disconnect()
调用close()
。最后,线程被阻塞
因此,您似乎需要更改逻辑。我假设您根据某些条件关闭连接。因此,在读取线程中的下一个字节之前,不要在不同的线程中检查条件,然后断开连接
顺便说一下,Thread.interrupt()
对您没有帮助,因为它只会在您等待IO时中断正在监视器上等待的线程。看起来,如果不更改读取线程以使用轮询并在没有可用字节时短暂休眠,则无法完成此操作,同时检查一些标志以查看线程是否应该结束
解决方案是只使用ApacheHTTP组件,通过将GET请求的代码封装在一个类中,可以很容易地集成到现有代码中
public class HttpGetConnection implements AutoCloseable {
public HttpGetConnection(String url) throws IOException {
client = new DefaultHttpClient();
get = new HttpGet(url);
response = client.execute(get);
entity = response.getEntity();
}
public InputStream getContent() throws IOException {
content = entity.getContent();
return content;
}
@Override
public void close() throws Exception {
get.abort();
try {
content.close();
}
catch (IOException e) {
}
}
private HttpClient client;
private HttpGet get;
private HttpResponse response;
private HttpEntity entity;
private InputStream content;
}
原始post中的循环可以保持原样,读取线程将在调用HttpGetConnection.close()
后不久死亡。另一种解决方法是将输入流包装到通道中并使用该通道(Channels.newChannel
),正如解决方案中所建议的那样。这将导致线程中断时关闭底层输入流。但是,JDK中有一条评论说,它实际上不可中断。在我的测试中,它似乎可以工作。我要求提供更多信息。谢谢。唯一的问题是,在大多数情况下,读取线程被阻塞,so它没有机会检查条件。InputStream
上没有允许超时的读取方法。您可以使用available()
查看流中是否有任何内容。如果没有,您可以暂停并在暂停后重新检查您的状态,这样您就不会阻塞空流。请查看我的答案-已经承认这一事实,并且它需要一个不太理想的轮询/睡眠/检查周期。无论如何,谢谢。@AlexGitelman找不到源代码。您介意吗更新你的链接?如果是这样的话,我认为没有人应该在不使用可用方法的情况下编写这样的代码。