Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 50 additions & 10 deletions widgets/easyWebsocketNative/src/EZWebsocketNative.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MutableRefObject, useEffect, useRef } from "react";
import { TextStyle, ViewStyle } from "react-native";
import { TextStyle, ViewStyle, AppState, AppStateStatus } from "react-native";

import { Style } from "@mendix/pluggable-widgets-tools";

Expand Down Expand Up @@ -30,26 +30,35 @@ export function EZWebsocketNative({
// Check if there is no open connection already
if (
connection.current === null &&
// Make sure all values are initiated
objectId.status === "available" &&
websocketIdentifier.status === "available" &&
(!messageAttribute || messageAttribute.status === "available") &&
(!onCloseMicroflowParameterValue || onCloseMicroflowParameterValue.status === "available") &&
(!actionConfig || !actionConfig.find(config => {
return config.action?.canExecute == false; //This check ensures parameters from Datasource flows are available in actions
}))
canStartConnection()
) {
startConnection();
}
}, [objectId, websocketIdentifier, messageAttribute, onCloseMicroflowParameterValue, actionConfig]);

useEffect(() => {
return () => {
// Close connection on unmount
// Close connection on unmount and empty connection ref so we can reconnect on remount
connection.current?.close();
connection.current = null;
};
}, []);

useEffect(() => {
//Add EventListener for AppState changes to be able to reconnect when the app comes back from background and connection was silently closed
const sub = AppState.addEventListener("change", (nextState: AppStateStatus) => {
if (nextState === "active") {
if (canStartConnection()) {
reconnect();
} else {
console.debug("Skipped reconnect on resume: parameters not ready yet");
}
}
});

return () => sub.remove();
}, []);

const startConnection = () => {
// Open websocket connection
// The replace action makes sure that applications without ssl connect to ws:// and with ssl connect to wss://
Expand Down Expand Up @@ -79,6 +88,10 @@ export function EZWebsocketNative({

ws.onclose = event => {
console.debug(event);

// Mark as closed so we can reconnect
connection.current = null;

// Timeout event
if (event.code === 1001 && timeoutAction && timeoutAction.canExecute) {
timeoutAction.execute();
Expand Down Expand Up @@ -128,5 +141,32 @@ export function EZWebsocketNative({
};
};

const reconnect = () => {
// If there is an existing socket, close it first
if (connection.current && connection.current.readyState !== WebSocket.CLOSED) {
try {
connection.current.close();
} catch (e) {
console.warn("Error while closing WS before reconnect", e);
}
}
connection.current = null;
startConnection();
};

const canStartConnection = (): boolean => {
return (
// Make sure all values are initiated. Made into reusable function as it is used in multiple places now
objectId.status === "available" &&
websocketIdentifier.status === "available" &&
(!messageAttribute || messageAttribute.status === "available") &&
(!onCloseMicroflowParameterValue || onCloseMicroflowParameterValue.status === "available") &&
(!actionConfig ||
!actionConfig.find(config => {
return config.action?.canExecute == false;
}))
);
};

return null;
}
Binary file modified widgets/tests/testProject/widgets/jjrplus.EZWebsocketNative.mpk
Binary file not shown.