Java httpClient:如何检查服务器端是否已关闭连接

Java httpClient:如何检查服务器端是否已关闭连接,java,apache,sockets,httpclient,Java,Apache,Sockets,Httpclient,我们连接到一个数据提供者,并使用HttpClient以无休止的循环读取XML数据。我们已经在Java代码中设置了连接超时和套接字超时。但是,当HTTP服务器端的连接关闭时,我们的应用程序不会抛出任何异常,只是挂起不做任何操作。由于这种行为,当服务器启动时,Java代码将不会重新连接。是否有任何方法可以查看服务器端是否已关闭套接字连接 此外,提到了如何关闭过时的连接,但它仍然不能解决我们的问题 提前非常感谢 代码段: private static final HttpClientConnectio

我们连接到一个数据提供者,并使用HttpClient以无休止的循环读取XML数据。我们已经在Java代码中设置了连接超时和套接字超时。但是,当HTTP服务器端的连接关闭时,我们的应用程序不会抛出任何异常,只是挂起不做任何操作。由于这种行为,当服务器启动时,Java代码将不会重新连接。是否有任何方法可以查看服务器端是否已关闭套接字连接

此外,提到了如何关闭过时的连接,但它仍然不能解决我们的问题

提前非常感谢

代码段:

private static final HttpClientConnectionManager CONN_MGR = new BasicHttpClientConnectionManager();

public boolean connectToServer() {
    disconnect();

    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
    provider.setCredentials(AuthScope.ANY, credentials);

    RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(15 * 1000)
            .setSocketTimeout(15 * 1000).build();

    HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider)
            .setSSLSocketFactory(sslsf)
            .setConnectionManager(CONN_MGR)
            .setDefaultRequestConfig(requestConfig).build();

    HttpGet request = new HttpGet(url);

    try {
        HttpResponse response = client.execute(request);
        in = response.getEntity().getContent();
        reader = new BufferedReader(new InputStreamReader(in));
        connected = true;

        return true;
    } catch (Exception re) {
        LOGGER.error("error", re);
    }

    return false;
}

public void process() {
    String xml = null;
    while (!shuttingDown) {
        try {

            /* if we know the server side closed the connection already here
               we can simply return and scheduler will take care of anything else. */

            xml = reader.readLine();
            lastSeen = System.currentTimeMillis();
            if (StringUtils.isBlank(xml)) {
                continue;
            }
            xml = xml.trim();

            // processing XML here
        } catch (IOException | NullPointerException ie) {
            /* We see SocketTimeoutException relatively often and
             * sometimes NullPointerException in reader.readLine(). */
            if (!shuttingDown) {
                if(!connectToServer()) {
                    break;
                }
            }
        } catch (RuntimeException re) {
            LOGGER.error("other RuntimeException", re);
            break;
        }
    }

    // the scheduler will start another processing.
    disconnect();
}

// called by the scheduler periodically
public boolean isConnected() {
    CONN_MGR.closeExpiredConnections();
    CONN_MGR.closeIdleConnections(15, TimeUnit.SECONDS);
    long now = System.currentTimeMillis();
    if (now - lastSeen > 15000L) {
        LOGGER.info("call disconnect() from isConnected().");
        disconnect();
    }

    return connected;
}

我认为随着Java1.7中自动资源管理的引入

清理陈旧的连接已经得到了注意,即使在最坏的情况下,实现提供商也会通过监视连接来仔细地进行清理


ApacheHttpClient使用HttpClientConnectionManager和其他实用程序类来清理陈旧的连接

我认为随着java 1.7中自动资源管理的引入

清理陈旧的连接已经得到了注意,即使在最坏的情况下,实现提供商也会通过监视连接来仔细地进行清理


ApacheHttpClient使用HttpClientConnectionManager和其他实用程序类来清理陈旧的连接

在最后一个catch块之后,为清理代码添加一个finally块

最后{ 连接经理关机(); }


根据文档,它关闭连接管理器并释放分配的资源

在最后一个catch块之后为清理代码添加finally块

最后{ 连接经理关机(); }


根据文档,它会关闭连接管理器并释放分配的资源

我们通过在15秒以上没有数据进入时关闭另一个线程的连接来避免问题。更具体地说,isConnected()方法如下所示:

// called by the scheduler periodically
public boolean isConnected() {
    long now = System.currentTimeMillis();
    if (now - lastSeen > 15000L) {
        disconnect();
    }

    return connected;
}
当然,阅读部分会java.net.SocketException:socketclosedjava.lang.IllegalStateException:发生这种情况时,仍会分配连接


更改后,一切正常。

当15秒以上没有数据输入时,我们关闭了另一个线程的连接,从而避免了问题。更具体地说,isConnected()方法如下所示:

// called by the scheduler periodically
public boolean isConnected() {
    long now = System.currentTimeMillis();
    if (now - lastSeen > 15000L) {
        disconnect();
    }

    return connected;
}
当然,阅读部分会java.net.SocketException:socketclosedjava.lang.IllegalStateException:发生这种情况时,仍会分配连接


更改后一切正常。

可能通过捕获IOException?In process()方法在捕获IOException或NullPointerException时,我们断开连接,然后重新连接。我创建了一个简单的HTTP服务器,并使用与代码相同的代码来查看CONN_MGR.closeExpiredConnections()是否有帮助。几分钟后,我关闭了HTTP服务器,代码仍然挂在xml=reader.readLine()上,没有任何错误或异常。请注意,每次调用CONN_MGR.closeExpiredConnections()时,我都会在日志文件中打印一条消息,并且我确实看到了这些消息。总之,CONN_MGR.closeExpiredConnections()会在我的代码中定期调用,但它不会以异常结束,因此我的代码不会重新连接。可能是通过捕获IOException?In process()来实现的方法当捕捉到IOException或NullPointerException时,我们断开连接,然后重新连接。我创建了一个简单的HTTP服务器,并使用与代码相同的代码查看CONN_MGR.closeExpiredConnections()是否有帮助。几分钟后,我关闭了HTTP服务器,代码仍然挂在xml=reader.readLine()上,没有任何错误或异常。请注意,每次调用CONN_MGR.closeExpiredConnections()时,我都会在日志文件中打印一条消息,并且我确实看到了这些消息。总之,CONN_MGR.closeExpiredConnections()会在我的代码中定期调用,但不会出现异常,因此我的代码不会重新连接。非常感谢您,Barath!最初我说关闭陈旧的连接没有帮助。很可能我错了,因为通常process()不会返回,它由Spring调度程序调用。因此,不会定期调用CONN_MGR.closeExpiredConnections()。我会让你知道CONN_MGR.closeExpiredConnections()是否有帮助。嗨@Barath!CONN_MGR.closeExpiredConnections()对我的案例没有帮助。有关详细信息,请参阅我帖子中的评论。非常感谢你,巴拉斯!最初我说关闭陈旧的连接没有帮助。很可能我错了,因为通常process()不会返回,它由Spring调度程序调用。因此,不会定期调用CONN_MGR.closeExpiredConnections()。我会让你知道CONN_MGR.closeExpiredConnections()是否有帮助。嗨@Barath!CONN_MGR.closeExpiredConnections()对我的案例没有帮助。有关详细信息,请参阅我帖子中的评论。谢谢你的回答,Ashish!不客气。如果你还有其他问题,请告诉我谢谢你的回答,阿什!不客气。如果您有其他问题,请告诉我