データプロバイダーに接続し、HttpClientを使用してXMLデータを無限ループで読み込みます。私たちはすでに、Javaコードで接続タイムアウトとソケットタイムアウトを設定しています。しかし、HTTPサーバー側で接続が閉じられると、アプリケーションは例外をスローせず、何もしないでハングします。この動作のために、サーバーが起動しているときにJavaコードは再接続しません。ソケット接続がサーバー側で既に閉じられているかどうかを確認する方法はありますか?httpClient:サーバー側で接続が既に閉じられているかどうかを確認する方法
さらに、https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.htmlはSTALE接続をクローズする方法について述べていますが、私たちの問題は解決していません。
ありがとうございます!
コードスニペット:私はJavaで自動リソース管理の導入失効した接続の最大クリーニング1.7
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
と考える
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;
}
おそらく* IOException *を捕まえることによって? –
IOExceptionまたはNullPointerExceptionがキャッチされたときのprocess()メソッドで、切断してから再接続します。 –
私は単純なHTTPサーバーを作成し、コードと同じコードを使用してCONN_MGR.closeExpiredConnections()が役立つかどうかを確認しました。数分後、私のコードはまだxml = reader.readLine()に何のエラーも例外もなくハングするHTTPサーバーをシャットダウンします。 CONN_MGR.closeExpiredConnections()が呼び出されるたびに注意してください。ログファイルにメッセージを出力して、実際にメッセージを見ました。言い換えれば、CONN_MGR.closeExpiredConnections()は自分のコードで定期的に呼び出されますが、私のコードが再接続しないようにExceptionで終わることはありません。 –