Disconnect all mobile clients when all UI clients leave

Summary: Context https://fb.workplace.com/groups/flippersupport/permalink/1730762380737746/

Reviewed By: lblasa

Differential Revision: D51510348

fbshipit-source-id: afafcdd6b89bf1038fec65a7c3e8c2dd9cfd0768
This commit is contained in:
Andrey Goncharov
2023-11-22 02:59:27 -08:00
committed by Facebook GitHub Bot
parent 1c706b52bc
commit 5693ac7205
6 changed files with 74 additions and 0 deletions

View File

@@ -59,6 +59,7 @@ import {DebuggableDevice} from './devices/DebuggableDevice';
import {jfUpload} from './fb-stubs/jf';
import path from 'path';
import {movePWA} from './utils/findInstallation';
import GK from './fb-stubs/GK';
const {access, copyFile, mkdir, unlink, stat, readlink, readFile, writeFile} =
promises;
@@ -109,6 +110,7 @@ export class FlipperServerImpl implements FlipperServer {
keytarManager: KeytarManager;
pluginManager: PluginManager;
unresponsiveClients: Set<string> = new Set();
private acceptingNewConections = true;
constructor(
public config: FlipperServerConfig,
@@ -175,6 +177,35 @@ export class FlipperServerImpl implements FlipperServer {
);
}
startAcceptingNewConections() {
if (!GK.get('flipper_disconnect_device_when_ui_offline')) {
return;
}
if (this.acceptingNewConections) {
return;
}
this.acceptingNewConections = true;
this.server.insecureServer?.startAcceptingNewConections();
this.server.altInsecureServer?.startAcceptingNewConections();
this.server.secureServer?.startAcceptingNewConections();
this.server.altSecureServer?.startAcceptingNewConections();
this.server.browserServer?.startAcceptingNewConections();
}
stopAcceptingNewConections() {
if (!GK.get('flipper_disconnect_device_when_ui_offline')) {
return;
}
this.acceptingNewConections = false;
this.server.insecureServer?.stopAcceptingNewConections();
this.server.altInsecureServer?.stopAcceptingNewConections();
this.server.secureServer?.stopAcceptingNewConections();
this.server.altSecureServer?.stopAcceptingNewConections();
this.server.browserServer?.stopAcceptingNewConections();
}
setServerState(state: FlipperServerState, error?: Error) {
this.state = state;
this.stateError = '' + error;

View File

@@ -148,6 +148,10 @@ class BrowserServerWebSocket extends SecureServerWebSocket {
protected verifyClient(): ws.VerifyClientCallbackSync {
return (info: {origin: string; req: IncomingMessage; secure: boolean}) => {
if (!this.acceptingNewConections) {
return false;
}
if (isFBBuild) {
try {
const urlObj = new URL(info.origin);

View File

@@ -293,6 +293,11 @@ class ServerRSocket extends ServerWebSocketBase {
},
};
};
protected stopAcceptingNewConectionsImpl(): void {
// Did not find a straightforard way to iterate through RSocket open connections and close them.
// We probably should not care and invest in it anyway as we are going to remove RScokets.
}
}
export default ServerRSocket;

View File

@@ -294,11 +294,20 @@ class ServerWebSocket extends ServerWebSocketBase {
*/
protected verifyClient(): VerifyClientCallbackSync {
return (_info: {origin: string; req: IncomingMessage; secure: boolean}) => {
if (!this.acceptingNewConections) {
return false;
}
// Client verification is not necessary. The connected client has
// already been verified using its certificate signed by the server.
return true;
};
}
protected stopAcceptingNewConectionsImpl(): void {
this.wsServer?.clients.forEach((client) =>
client.close(WSCloseCode.GoingAway),
);
}
}
export default ServerWebSocket;

View File

@@ -15,6 +15,7 @@ import {
SignCertificateMessage,
} from 'flipper-common';
import {SecureServerConfig} from './certificate-exchange/certificate-utils';
import GK from '../fb-stubs/GK';
/**
* Defines an interface for events triggered by a running server interacting
@@ -98,6 +99,8 @@ export interface ServerEventsListener {
* RSocket, WebSocket, etc.
*/
abstract class ServerWebSocketBase {
protected acceptingNewConections = true;
constructor(protected listener: ServerEventsListener) {}
/**
@@ -169,6 +172,23 @@ abstract class ServerWebSocketBase {
return undefined;
}
startAcceptingNewConections() {
if (!GK.get('flipper_disconnect_device_when_ui_offline')) {
return;
}
this.acceptingNewConections = true;
}
stopAcceptingNewConections() {
if (!GK.get('flipper_disconnect_device_when_ui_offline')) {
return;
}
this.acceptingNewConections = false;
this.stopAcceptingNewConectionsImpl();
}
protected abstract stopAcceptingNewConectionsImpl(): void;
}
export default ServerWebSocketBase;

View File

@@ -72,6 +72,7 @@ export function attachSocketServer(
server.emit('browser-connection-created', {});
let connected = true;
server.startAcceptingNewConections();
let flipperServerCompanion: FlipperServerCompanion | undefined;
if (req.url) {
@@ -253,6 +254,10 @@ export function attachSocketServer(
sessionLength: performance.now() - t0,
});
if (numberOfConnectedClients === 0) {
server.stopAcceptingNewConections();
}
if (
getFlipperServerConfig().environmentInfo.isHeadlessBuild &&
isProduction()