[remoteopenhab] New setting to restart the SSE connection after inact… (#10063)
* [remoteopenhab] New setting to restart the SSE connection after inactivity Fix #9680 Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Review comments: doc Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
@@ -35,4 +35,5 @@ public class RemoteopenhabServerConfiguration {
|
||||
public String token = "";
|
||||
public int accessibilityInterval = 3;
|
||||
public int aliveInterval = 5;
|
||||
public boolean restartIfNoActivity = false;
|
||||
}
|
||||
|
||||
@@ -174,9 +174,9 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
scheduler.submit(this::checkConnection);
|
||||
scheduler.submit(() -> checkConnection(false));
|
||||
if (config.accessibilityInterval > 0) {
|
||||
startCheckConnectionJob(config.accessibilityInterval, config.aliveInterval);
|
||||
startCheckConnectionJob(config.accessibilityInterval, config.aliveInterval, config.restartIfNoActivity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
|
||||
}
|
||||
}
|
||||
|
||||
public void checkConnection() {
|
||||
public void checkConnection(boolean restartSse) {
|
||||
logger.debug("Try the root REST API...");
|
||||
try {
|
||||
restClient.tryApi();
|
||||
@@ -367,6 +367,9 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
|
||||
"Dynamic creation of the channels for the remote server items failed");
|
||||
stopStreamingUpdates();
|
||||
}
|
||||
} else if (restartSse) {
|
||||
logger.debug("The SSE connection is restarted because there was no recent event received");
|
||||
restartStreamingUpdates();
|
||||
}
|
||||
} catch (RemoteopenhabException e) {
|
||||
logger.debug("{}", e.getMessage());
|
||||
@@ -375,7 +378,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
|
||||
}
|
||||
}
|
||||
|
||||
private void startCheckConnectionJob(int accessibilityInterval, int aliveInterval) {
|
||||
private void startCheckConnectionJob(int accessibilityInterval, int aliveInterval, boolean restartIfNoActivity) {
|
||||
ScheduledFuture<?> localCheckConnectionJob = checkConnectionJob;
|
||||
if (localCheckConnectionJob == null || localCheckConnectionJob.isCancelled()) {
|
||||
checkConnectionJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||
@@ -383,12 +386,12 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
|
||||
if (getThing().getStatus() != ThingStatus.ONLINE || aliveInterval == 0
|
||||
|| restClient.getLastEventTimestamp() == 0) {
|
||||
logger.debug("Time to check server accessibility");
|
||||
checkConnection();
|
||||
checkConnection(restartIfNoActivity && aliveInterval != 0);
|
||||
} else if (millisSinceLastEvent > (aliveInterval * 60000)) {
|
||||
logger.debug(
|
||||
"Time to check server accessibility (maybe disconnected from streaming events, millisSinceLastEvent={})",
|
||||
millisSinceLastEvent);
|
||||
checkConnection();
|
||||
checkConnection(restartIfNoActivity);
|
||||
} else {
|
||||
logger.debug(
|
||||
"Bypass server accessibility check (receiving streaming events, millisSinceLastEvent={})",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.remoteopenhab.internal.rest;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
@@ -21,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@@ -182,7 +184,7 @@ public class RemoteopenhabRestClient {
|
||||
public void sendCommandToRemoteItem(String itemName, Command command) throws RemoteopenhabException {
|
||||
try {
|
||||
String url = String.format("%s/%s", getRestApiUrl("items"), itemName);
|
||||
executeUrl(HttpMethod.POST, url, "application/json", command.toFullString(), "text/plain", false);
|
||||
executeUrl(HttpMethod.POST, url, "application/json", command.toFullString(), "text/plain", false, true);
|
||||
} catch (RemoteopenhabException e) {
|
||||
throw new RemoteopenhabException("Failed to send command to the remote item " + itemName
|
||||
+ " using the items REST API: " + e.getMessage(), e);
|
||||
@@ -470,11 +472,11 @@ public class RemoteopenhabRestClient {
|
||||
}
|
||||
|
||||
public String executeGetUrl(String url, String acceptHeader, boolean asyncReading) throws RemoteopenhabException {
|
||||
return executeUrl(HttpMethod.GET, url, acceptHeader, null, null, asyncReading);
|
||||
return executeUrl(HttpMethod.GET, url, acceptHeader, null, null, asyncReading, true);
|
||||
}
|
||||
|
||||
public String executeUrl(HttpMethod httpMethod, String url, String acceptHeader, @Nullable String content,
|
||||
@Nullable String contentType, boolean asyncReading) throws RemoteopenhabException {
|
||||
@Nullable String contentType, boolean asyncReading, boolean retryIfEOF) throws RemoteopenhabException {
|
||||
final Request request = httpClient.newRequest(url).method(httpMethod).timeout(REQUEST_TIMEOUT,
|
||||
TimeUnit.MILLISECONDS);
|
||||
|
||||
@@ -517,6 +519,16 @@ public class RemoteopenhabRestClient {
|
||||
}
|
||||
} catch (RemoteopenhabException e) {
|
||||
throw e;
|
||||
} catch (ExecutionException e) {
|
||||
// After a long network outage, the first HTTP request will fail with an EOFException exception.
|
||||
// We retry the request a second time in this case.
|
||||
Throwable cause = e.getCause();
|
||||
if (retryIfEOF && cause instanceof EOFException) {
|
||||
logger.debug("EOFException - retry the request");
|
||||
return executeUrl(httpMethod, url, acceptHeader, content, contentType, asyncReading, false);
|
||||
} else {
|
||||
throw new RemoteopenhabException(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RemoteopenhabException(e);
|
||||
}
|
||||
|
||||
@@ -63,11 +63,24 @@
|
||||
|
||||
<parameter name="aliveInterval" type="integer" min="0" step="1" unit="min">
|
||||
<label>Alive Interval</label>
|
||||
<description>Number of last minutes to take into account to determine whether the remote server is alive. 0 to
|
||||
disable this feature. Default is 5.</description>
|
||||
<description>Number of last minutes to consider when monitoring the receipt of events from the remote server. If an
|
||||
event is received during this interval, the remote server is considered alive and its accessibility will not be
|
||||
verified. Use 0 to disable this feature. Default is 5.</description>
|
||||
<default>5</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
|
||||
<parameter name="restartIfNoActivity" type="boolean">
|
||||
<label>Restart if no Activity</label>
|
||||
<description>Set it to true if you want to restart the connection (SSE) to the remote server when no events are
|
||||
received in the monitored interval. It is not necessary if the goal is to properly handle a short network outage
|
||||
(few seconds). This can be useful if you want to deal with a long network outage. Do not enable it if you remote
|
||||
server does not send events during the monitored interval under normal conditions, it will cause frequent restart
|
||||
of the connection and potential loss of events. Default is false.
|
||||
</description>
|
||||
<default>false</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user