[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:
parent
3e7ecbf79c
commit
5141781fe7
@ -45,7 +45,8 @@ The `server` thing has the following configuration parameters:
|
||||
| restPath | yes | The subpath of the REST API on the remote openHAB server. Default is /rest |
|
||||
| token | no | The token to use when the remote openHAB server is setup to require authorization to run its REST API. |
|
||||
| accessibilityInterval | no | Minutes between checking the remote server accessibility. 0 to disable the check. Default is 3. |
|
||||
| aliveInterval | no | Number of last minutes to take into account to determine whether the remote server is alive. 0 to disable this feature. Default is 5. |
|
||||
| aliveInterval | no | 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. |
|
||||
| restartIfNoActivity | no | 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. |
|
||||
|
||||
The `thing` thing has the following configuration parameters:
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user