in desktop/flipper-server/src/startSocketServer.tsx [21:133]
export function startSocketServer(
flipperServer: FlipperServerImpl,
socket: WebSocketServer,
) {
socket.on('connection', (client, req) => {
const clientAddress =
(req.socket.remoteAddress &&
` ${req.socket.remoteAddress}:${req.socket.remotePort}`) ||
'';
console.log(chalk.green(`Client connected${clientAddress}`));
let connected = true;
function onServerEvent(event: string, payload: any) {
const message = {
event: 'server-event',
payload: {
event,
data: payload,
},
} as ServerEventWebSocketMessage;
client.send(JSON.stringify(message));
}
flipperServer.onAny(onServerEvent);
client.on('message', (data) => {
let [event, payload]: [event: string | null, payload: any | null] = [
null,
null,
];
try {
({event, payload} = JSON.parse(
data.toString(),
) as ClientWebSocketMessage);
} catch (err) {
console.warn('flipperServer -> onMessage: failed to parse JSON', err);
const response: GenericWebSocketError = {
event: 'error',
payload: {message: `Failed to parse JSON request: ${err}`},
};
client.send(JSON.stringify(response));
return;
}
switch (event) {
case 'exec': {
const {id, command, args} = payload;
if (typeof args[Symbol.iterator] !== 'function') {
console.warn(
'flipperServer -> exec: args argument in payload is not iterable',
);
const responseError: ExecResponseErrorWebSocketMessage = {
event: 'exec-response-error',
payload: {
id,
data: 'Payload args argument is not an iterable.',
},
};
client.send(JSON.stringify(responseError));
return;
}
flipperServer
.exec(command, ...args)
.then((result: any) => {
if (connected) {
const response: ExecResponseWebSocketMessage = {
event: 'exec-response',
payload: {
id,
data: result,
},
};
client.send(JSON.stringify(response));
}
})
.catch((error: any) => {
if (connected) {
// TODO: Serialize error
// TODO: log if verbose console.warn('Failed to handle response', error);
const responseError: ExecResponseErrorWebSocketMessage = {
event: 'exec-response-error',
payload: {
id,
data:
error.toString() +
(error.stack ? `\n${error.stack}` : ''),
},
};
client.send(JSON.stringify(responseError));
}
});
}
}
});
client.on('close', () => {
console.log(chalk.red(`Client disconnected ${clientAddress}`));
connected = false;
flipperServer.offAny(onServerEvent);
});
client.on('error', (e) => {
console.error(chalk.red(`Socket error ${clientAddress}`), e);
connected = false;
flipperServer.offAny(onServerEvent);
});
});
}