mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[freeboxos] Fix websocket registration (#17124)
Fix #17098 Signed-off-by: Laurent Garnier <lg.hc@free.fr> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
16c2b2ef74
commit
4d45b65917
@ -60,6 +60,7 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
private static final String HOST_REACHABLE = "lan_host_l3addr_reachable";
|
||||
private static final String VM_CHANGED = "vm_state_changed";
|
||||
private static final Register REGISTRATION = new Register(VM_CHANGED, HOST_REACHABLE, HOST_UNREACHABLE);
|
||||
private static final Register REGISTRATION_WITHOUT_VM = new Register(HOST_REACHABLE, HOST_UNREACHABLE);
|
||||
private static final String WS_PATH = "ws/event";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(WebSocketManager.class);
|
||||
@ -69,6 +70,11 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
private final WebSocketClient client;
|
||||
private Optional<ScheduledFuture<?>> reconnectJob = Optional.empty();
|
||||
private volatile @Nullable Session wsSession;
|
||||
@Nullable
|
||||
private String sessionToken;
|
||||
private int reconnectInterval;
|
||||
private boolean vmSupported = true;
|
||||
private boolean retryConnectWithoutVm = false;
|
||||
|
||||
private record Register(String action, List<String> events) {
|
||||
Register(String... events) {
|
||||
@ -88,40 +94,45 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
private static record WebSocketResponse(boolean success, Action action, String event, String source,
|
||||
@Nullable JsonElement result) {
|
||||
private static record WebSocketResponse(boolean success, @Nullable String msg, Action action, String event,
|
||||
String source, @Nullable JsonElement result) {
|
||||
public String getEvent() {
|
||||
return source + "_" + event;
|
||||
}
|
||||
}
|
||||
|
||||
public void openSession(@Nullable String sessionToken, int reconnectInterval) {
|
||||
this.sessionToken = sessionToken;
|
||||
this.reconnectInterval = reconnectInterval;
|
||||
if (reconnectInterval > 0) {
|
||||
URI uri = getUriBuilder().scheme(getUriBuilder().build().getScheme().contains("s") ? "wss" : "ws").build();
|
||||
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||
request.setHeader(ApiHandler.AUTH_HEADER, sessionToken);
|
||||
try {
|
||||
client.start();
|
||||
stopReconnect();
|
||||
reconnectJob = Optional.of(scheduler.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
closeSession();
|
||||
client.connect(this, uri, request);
|
||||
// Update listeners in case we would have lost data while disconnecting / reconnecting
|
||||
listeners.values()
|
||||
.forEach(host -> host.handleCommand(new ChannelUID(host.getThing().getUID(), REACHABLE),
|
||||
RefreshType.REFRESH));
|
||||
logger.debug("Websocket manager connected to {}", uri);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error connecting websocket client: {}", e.getMessage());
|
||||
}
|
||||
}, 0, reconnectInterval, TimeUnit.MINUTES));
|
||||
startReconnect();
|
||||
} catch (Exception e) {
|
||||
logger.warn("Error starting websocket client: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startReconnect() {
|
||||
URI uri = getUriBuilder().scheme(getUriBuilder().build().getScheme().contains("s") ? "wss" : "ws").build();
|
||||
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||
request.setHeader(ApiHandler.AUTH_HEADER, sessionToken);
|
||||
stopReconnect();
|
||||
reconnectJob = Optional.of(scheduler.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
closeSession();
|
||||
client.connect(this, uri, request);
|
||||
// Update listeners in case we would have lost data while disconnecting / reconnecting
|
||||
listeners.values().forEach(host -> host
|
||||
.handleCommand(new ChannelUID(host.getThing().getUID(), REACHABLE), RefreshType.REFRESH));
|
||||
logger.debug("Websocket manager connected to {}", uri);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error connecting websocket client: {}", e.getMessage());
|
||||
}
|
||||
}, 0, reconnectInterval, TimeUnit.MINUTES));
|
||||
}
|
||||
|
||||
private void stopReconnect() {
|
||||
reconnectJob.ifPresent(job -> job.cancel(true));
|
||||
reconnectJob = Optional.empty();
|
||||
@ -151,7 +162,8 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
this.wsSession = wsSession;
|
||||
logger.debug("Websocket connection establisehd");
|
||||
try {
|
||||
wsSession.getRemote().sendString(apiHandler.serialize(REGISTRATION));
|
||||
wsSession.getRemote()
|
||||
.sendString(apiHandler.serialize(vmSupported ? REGISTRATION : REGISTRATION_WITHOUT_VM));
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error registering to websocket: {}", e.getMessage());
|
||||
}
|
||||
@ -159,6 +171,7 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(@NonNullByDefault({}) String message) {
|
||||
logger.debug("Websocket: received message: {}", message);
|
||||
Session localSession = wsSession;
|
||||
if (message.toLowerCase(Locale.US).contains("bye") && localSession != null) {
|
||||
localSession.close(StatusCode.NORMAL, "Thanks");
|
||||
@ -177,6 +190,12 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
default:
|
||||
logger.warn("Unhandled notification received: {}", result.action);
|
||||
}
|
||||
} else if (result.action == Action.REGISTER) {
|
||||
logger.debug("Event registration failed!");
|
||||
if (vmSupported && "unsupported event vm_state_changed".equals(result.msg)) {
|
||||
vmSupported = false;
|
||||
retryConnectWithoutVm = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,6 +215,9 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
LanHost host = apiHandler.deserialize(LanHost.class, json.toString());
|
||||
ApiConsumerHandler handler2 = listeners.get(host.getMac());
|
||||
if (handler2 instanceof HostHandler hostHandler) {
|
||||
logger.debug("Received notification for mac {} : thing {} is {}reachable",
|
||||
host.getMac().toColonDelimitedString(), hostHandler.getThing().getUID(),
|
||||
host.reachable() ? "" : "not ");
|
||||
hostHandler.updateConnectivityChannels(host);
|
||||
}
|
||||
break;
|
||||
@ -211,6 +233,11 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
|
||||
public void onWebSocketClose(int statusCode, @NonNullByDefault({}) String reason) {
|
||||
logger.debug("Socket Closed: [{}] - reason {}", statusCode, reason);
|
||||
this.wsSession = null;
|
||||
if (retryConnectWithoutVm) {
|
||||
logger.debug("Retry connecting websocket client without VM support");
|
||||
retryConnectWithoutVm = false;
|
||||
startReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user