Add flipper-server-companion to flipper-server
Summary: Start flipper-server-companion whenever a client connects to flipper-server and sets `server_companion` query parameter in a connection URL to true Reviewed By: mweststrate Differential Revision: D36098169 fbshipit-source-id: eb953e7d680b30aef1340f059264112387264c05
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a6d7f98cfd
commit
b4498f070f
@@ -27,6 +27,7 @@
|
|||||||
"flipper-pkg-lib": "0.0.0",
|
"flipper-pkg-lib": "0.0.0",
|
||||||
"flipper-server-core": "0.0.0",
|
"flipper-server-core": "0.0.0",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
|
"flipper-server-companion": "0.0.0",
|
||||||
"metro": "^0.70.2",
|
"metro": "^0.70.2",
|
||||||
"open": "^8.3.0",
|
"open": "^8.3.0",
|
||||||
"p-filter": "^2.1.0",
|
"p-filter": "^2.1.0",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {startWebServerDev} from './startWebServerDev';
|
|||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import open from 'open';
|
import open from 'open';
|
||||||
import {sleep} from 'flipper-common';
|
import {sleep} from 'flipper-common';
|
||||||
|
import {initCompanionEnv} from 'flipper-server-companion';
|
||||||
|
|
||||||
const argv = yargs
|
const argv = yargs
|
||||||
.usage('yarn flipper-server [args]')
|
.usage('yarn flipper-server [args]')
|
||||||
@@ -88,6 +89,7 @@ async function start() {
|
|||||||
argv.settingsString,
|
argv.settingsString,
|
||||||
argv.launcherSettings,
|
argv.launcherSettings,
|
||||||
);
|
);
|
||||||
|
const companionEnv = await initCompanionEnv(flipperServer);
|
||||||
if (argv.failFast) {
|
if (argv.failFast) {
|
||||||
flipperServer.on('server-state', ({state}) => {
|
flipperServer.on('server-state', ({state}) => {
|
||||||
if (state === 'error') {
|
if (state === 'error') {
|
||||||
@@ -100,7 +102,7 @@ async function start() {
|
|||||||
if (argv.bundler) {
|
if (argv.bundler) {
|
||||||
await startWebServerDev(app, server, socket, rootDir);
|
await startWebServerDev(app, server, socket, rootDir);
|
||||||
}
|
}
|
||||||
startSocketServer(flipperServer, socket);
|
startSocketServer(flipperServer, socket, companionEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -16,13 +16,20 @@ import {
|
|||||||
GenericWebSocketError,
|
GenericWebSocketError,
|
||||||
UserError,
|
UserError,
|
||||||
SystemError,
|
SystemError,
|
||||||
|
getLogger,
|
||||||
} from 'flipper-common';
|
} from 'flipper-common';
|
||||||
import {FlipperServerImpl} from 'flipper-server-core';
|
import {FlipperServerImpl} from 'flipper-server-core';
|
||||||
import {WebSocketServer} from 'ws';
|
import {WebSocketServer} from 'ws';
|
||||||
|
import {
|
||||||
|
FlipperServerCompanion,
|
||||||
|
FlipperServerCompanionEnv,
|
||||||
|
} from 'flipper-server-companion';
|
||||||
|
import {URLSearchParams} from 'url';
|
||||||
|
|
||||||
export function startSocketServer(
|
export function startSocketServer(
|
||||||
flipperServer: FlipperServerImpl,
|
flipperServer: FlipperServerImpl,
|
||||||
socket: WebSocketServer,
|
socket: WebSocketServer,
|
||||||
|
companionEnv: FlipperServerCompanionEnv,
|
||||||
) {
|
) {
|
||||||
socket.on('connection', (client, req) => {
|
socket.on('connection', (client, req) => {
|
||||||
const clientAddress =
|
const clientAddress =
|
||||||
@@ -34,7 +41,52 @@ export function startSocketServer(
|
|||||||
|
|
||||||
let connected = true;
|
let connected = true;
|
||||||
|
|
||||||
function onServerEvent(event: string, payload: any) {
|
let flipperServerCompanion: FlipperServerCompanion | undefined;
|
||||||
|
if (req.url) {
|
||||||
|
const params = new URLSearchParams(req.url.slice(1));
|
||||||
|
|
||||||
|
if (params.get('server_companion')) {
|
||||||
|
flipperServerCompanion = new FlipperServerCompanion(
|
||||||
|
flipperServer,
|
||||||
|
getLogger(),
|
||||||
|
companionEnv.pluginInitializer.loadedPlugins,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onServerEvent(event: string, payload: any) {
|
||||||
|
if (flipperServerCompanion) {
|
||||||
|
switch (event) {
|
||||||
|
case 'client-message': {
|
||||||
|
const client = flipperServerCompanion.getClient(payload.id);
|
||||||
|
if (!client) {
|
||||||
|
console.warn(
|
||||||
|
'flipperServerCompanion.handleClientMessage -> unknown client',
|
||||||
|
event,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.onMessage(payload.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'client-disconnected': {
|
||||||
|
if (flipperServerCompanion.getClient(payload.id)) {
|
||||||
|
flipperServerCompanion.destroyClient(payload.id);
|
||||||
|
}
|
||||||
|
// We use "break" here instead of "return" because a flipper desktop client still might be interested in the "client-disconnect" event to update its list of active clients
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'device-disconnected': {
|
||||||
|
if (flipperServerCompanion.getDevice(payload.id)) {
|
||||||
|
flipperServerCompanion.destroyDevice(payload.id);
|
||||||
|
}
|
||||||
|
// We use "break" here instead of "return" because a flipper desktop client still might be interested in the "device-disconnect" event to update its list of active devices
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
event: 'server-event',
|
event: 'server-event',
|
||||||
payload: {
|
payload: {
|
||||||
@@ -85,8 +137,11 @@ export function startSocketServer(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
flipperServer
|
const execRes = flipperServerCompanion?.canHandleCommand(command)
|
||||||
.exec(command, ...args)
|
? flipperServerCompanion.exec(command, ...args)
|
||||||
|
: flipperServer.exec(command, ...args);
|
||||||
|
|
||||||
|
execRes
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
const response: ExecResponseWebSocketMessage = {
|
const response: ExecResponseWebSocketMessage = {
|
||||||
@@ -138,12 +193,14 @@ export function startSocketServer(
|
|||||||
console.log(chalk.red(`Client disconnected ${clientAddress}`));
|
console.log(chalk.red(`Client disconnected ${clientAddress}`));
|
||||||
connected = false;
|
connected = false;
|
||||||
flipperServer.offAny(onServerEvent);
|
flipperServer.offAny(onServerEvent);
|
||||||
|
flipperServerCompanion?.destroyAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('error', (e) => {
|
client.on('error', (e) => {
|
||||||
console.error(chalk.red(`Socket error ${clientAddress}`), e);
|
console.error(chalk.red(`Socket error ${clientAddress}`), e);
|
||||||
connected = false;
|
connected = false;
|
||||||
flipperServer.offAny(onServerEvent);
|
flipperServer.offAny(onServerEvent);
|
||||||
|
flipperServerCompanion?.destroyAll();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
|
"lib": ["ES2019"],
|
||||||
"types": ["../types/flipperGlobals", "../types/metro-resolver", "../types/metro"]
|
"types": ["../types/flipperGlobals", "../types/metro-resolver", "../types/metro"]
|
||||||
},
|
},
|
||||||
"include": ["./src/*"],
|
"include": ["./src/*"],
|
||||||
@@ -13,6 +14,9 @@
|
|||||||
{
|
{
|
||||||
"path": "../flipper-server-core"
|
"path": "../flipper-server-core"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../flipper-server-companion"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../pkg-lib"
|
"path": "../pkg-lib"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user