diff --git a/desktop/app/src/dispatcher/application.tsx b/desktop/app/src/dispatcher/application.tsx index 43d1677e4..058a1e52a 100644 --- a/desktop/app/src/dispatcher/application.tsx +++ b/desktop/app/src/dispatcher/application.tsx @@ -94,4 +94,20 @@ export default (store: Store, _logger: Logger) => { ); } } + + if (process.env.FLIPPER_ALT_PORTS) { + const portOverrides = parseFlipperPorts(process.env.FLIPPER_ALT_PORTS); + if (portOverrides) { + store.dispatch({ + type: 'SET_ALT_SERVER_PORTS', + payload: portOverrides, + }); + } else { + console.error( + `Ignoring malformed FLIPPER_ALT_PORTS env variable: + "${process.env.FLIPPER_ALT_PORTS || ''}". + Example expected format: "1111,2222".`, + ); + } + } }; diff --git a/desktop/app/src/reducers/application.tsx b/desktop/app/src/reducers/application.tsx index dc229b357..13a2973c3 100644 --- a/desktop/app/src/reducers/application.tsx +++ b/desktop/app/src/reducers/application.tsx @@ -83,6 +83,7 @@ export type State = { share: ShareType | null; sessionId: string | null; serverPorts: ServerPorts; + altServerPorts: ServerPorts; launcherMsg: LauncherMsg; statusMessages: Array; pastedToken?: string; @@ -121,6 +122,13 @@ export type Action = secure: number; }; } + | { + type: 'SET_ALT_SERVER_PORTS'; + payload: { + insecure: number; + secure: number; + }; + } | { type: 'LAUNCHER_MSG'; payload: { @@ -164,6 +172,10 @@ export const initialState: () => State = () => ({ insecure: 8089, secure: 8088, }, + altServerPorts: { + insecure: 9089, + secure: 9088, + }, launcherMsg: { severity: 'warning', message: '', @@ -238,6 +250,11 @@ export default function reducer( ...state, serverPorts: action.payload, }; + } else if (action.type === 'SET_ALT_SERVER_PORTS') { + return { + ...state, + altServerPorts: action.payload, + }; } else if (action.type === 'LAUNCHER_MSG') { return { ...state, diff --git a/desktop/app/src/server/comms/ServerController.tsx b/desktop/app/src/server/comms/ServerController.tsx index 72d5df65e..457512015 100644 --- a/desktop/app/src/server/comms/ServerController.tsx +++ b/desktop/app/src/server/comms/ServerController.tsx @@ -31,7 +31,11 @@ import ServerAdapter, { SecureClientQuery, ServerEventsListener, } from './ServerAdapter'; -import {createBrowserServer, createServer} from './ServerFactory'; +import { + createBrowserServer, + createServer, + TransportType, +} from './ServerFactory'; import {FlipperServer} from '../FlipperServer'; import {isTest} from '../../utils/isProduction'; import {timeout} from 'flipper-plugin'; @@ -66,6 +70,8 @@ class ServerController extends EventEmitter implements ServerEventsListener { initialized: Promise | null; secureServer: Promise | null; insecureServer: Promise | null; + altSecureServer: Promise | null; + altInsecureServer: Promise | null; browserServer: Promise | null; certificateProvider: CertificateProvider; @@ -87,6 +93,8 @@ class ServerController extends EventEmitter implements ServerEventsListener { this.connectionTracker = new ConnectionTracker(this.logger); this.secureServer = null; this.insecureServer = null; + this.altSecureServer = null; + this.altInsecureServer = null; this.browserServer = null; this.initialized = null; this.timeHandler = undefined; @@ -113,13 +121,34 @@ class ServerController extends EventEmitter implements ServerEventsListener { throw new Error('Spawing new server is not supported in test'); } const {insecure, secure} = this.store.getState().application.serverPorts; + this.initialized = this.certificateProvider .loadSecureServerConfig() - .then( - (options) => (this.secureServer = createServer(secure, this, options)), - ) + .then((options) => { + this.secureServer = createServer(secure, this, options); + if (GK.get('flipper_websocket_server')) { + const {secure: altSecure} = + this.store.getState().application.altServerPorts; + this.altSecureServer = createServer( + altSecure, + this, + options, + TransportType.WebSocket, + ); + } + }) .then(() => { this.insecureServer = createServer(insecure, this); + if (GK.get('flipper_websocket_server')) { + const {insecure: altInsecure} = + this.store.getState().application.altServerPorts; + this.altInsecureServer = createServer( + altInsecure, + this, + undefined, + TransportType.WebSocket, + ); + } return; }); @@ -140,6 +169,8 @@ class ServerController extends EventEmitter implements ServerEventsListener { await Promise.all([ this.insecureServer && (await this.insecureServer).stop(), this.secureServer && (await this.secureServer).stop(), + this.altInsecureServer && (await this.altInsecureServer).stop(), + this.altSecureServer && (await this.altSecureServer).stop(), this.browserServer && (await this.browserServer).stop(), ]); } diff --git a/desktop/app/src/server/comms/ServerFactory.tsx b/desktop/app/src/server/comms/ServerFactory.tsx index 2b962e9db..348bfc3a2 100644 --- a/desktop/app/src/server/comms/ServerFactory.tsx +++ b/desktop/app/src/server/comms/ServerFactory.tsx @@ -7,24 +7,15 @@ * @format */ -import GK from '../../fb-stubs/GK'; import {SecureServerConfig} from '../utils/CertificateProvider'; import ServerAdapter, {ServerEventsListener} from './ServerAdapter'; import ServerRSocket from './ServerRSocket'; import ServerWebSocket from './ServerWebSocket'; import ServerWebSocketBrowser from './ServerWebSocketBrowser'; -function _createServer(listener: ServerEventsListener) { - /** - * GK could be setup or queried to determine whether to use RSocket or - * WebSocket. Default is RSocket, but the stage is set for different type - * of communication channels. - */ - if (GK.get('flipper_websocket_server')) { - return new ServerWebSocket(listener); - } - - return new ServerRSocket(listener); +export enum TransportType { + RSocket, + WebSocket, } /** @@ -38,9 +29,13 @@ export function createServer( port: number, listener: ServerEventsListener, sslConfig?: SecureServerConfig, + transportType: TransportType = TransportType.RSocket, ): Promise { return new Promise((resolve, reject) => { - const server = _createServer(listener); + const server = + transportType === TransportType.RSocket + ? new ServerRSocket(listener) + : new ServerWebSocket(listener); server .start(port, sslConfig) .then((started) => {