diff --git a/app-shell/src/notifications/connect.ts b/app-shell/src/notifications/connect.ts index bcaf24e6e3d..ed46b4aa7b6 100644 --- a/app-shell/src/notifications/connect.ts +++ b/app-shell/src/notifications/connect.ts @@ -68,6 +68,7 @@ export function establishConnections( ): Promise { return new Promise((resolve, reject) => { const newConnections = healthyRobots.filter(({ ip, robotName }) => { + // Only attempt a new connection if the current broker connection is bad. if (connectionStore.isConnectedToBroker(robotName)) { return false } else { @@ -171,7 +172,7 @@ function establishListeners( client.on('reconnect', () => { notifyLog.debug(`Attempting to reconnect to ${robotName} on ${ip}`) }) - // handles transport layer errors only + // Handles transport layer errors only client.on('error', error => { notifyLog.warn(`Error - ${error.name}: ${error.message}`) sendDeserializedGenericError(ip, 'ALL_TOPICS') @@ -193,6 +194,15 @@ function establishListeners( ) sendDeserializedGenericError(ip, 'ALL_TOPICS') }) + + // Some network interfaces (such as link-local) will *sometimes* fire the 'offline' event when physically disconnected. + // While the keepalive packet will eventually result in an 'error' event and close the client, we can proactively + // close the client when possible, allowing for the connection store to connect to the robot on an alternative IP + // if one is available. + client.on('offline', () => { + sendDeserializedGenericError(ip, 'ALL_TOPICS') + client.end() + }) } export function closeConnectionsForcefullyFor(