Skip to content

Commit

Permalink
Add Github pages link to readme, folder cleanup (#577)
Browse files Browse the repository at this point in the history
### Public-Facing Changes

None

### Description
- Moves the test client web app package to the top level directory
- Adds a link to Github pages where the test client is hosted
  • Loading branch information
achim-k authored Nov 6, 2023
1 parent 10c78ef commit bd960ad
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ Implementations are available in the following languages:
| C++ | [server + examples](cpp) | `foxglove-websocket` | [![](https://shields.io/conan/v/foxglove-websocket)](https://conan.io/center/foxglove-websocket) |

### Additional resources

- https://foxglove.github.io/ws-protocol - Connect to a ws-protocol compliant server and measure data throughput
- [eCAL Foxglove Bridge](https://github.com/eclipse-ecal/ecal-foxglove-bridge) – WebSocket bridge that allows users to connect eCAL systems to Foxglove Studio for easy visualization and debugging

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"private": true,
"workspaces": {
"packages": [
"typescript/*"
"typescript/*",
"test-client-web-app"
]
}
}
22 changes: 22 additions & 0 deletions test-client-web-app/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-env node */
module.exports = {
env: { es2020: true },
ignorePatterns: ["dist"],
extends: ["plugin:@foxglove/base", "plugin:@foxglove/jest"],
overrides: [
{
files: ["*.ts", "*.tsx"],
extends: ["plugin:@foxglove/typescript"],
parserOptions: {
project: "./tsconfig.json",
tsconfigRootDir: __dirname,
},
},
],
rules: {
"no-warning-comments": [
"error",
{ terms: ["fixme"], location: "anywhere" },
],
},
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,22 @@ import {
Tooltip,
Typography,
} from "@mui/material";
import { BarElement, CategoryScale, Chart as ChartJS, Legend, LinearScale, Title } from "chart.js";
import { memo, useCallback, useEffect, useRef, useState, ReactElement } from "react";
import {
BarElement,
CategoryScale,
Chart as ChartJS,
Legend,
LinearScale,
Title,
} from "chart.js";
import {
memo,
useCallback,
useEffect,
useRef,
useState,
ReactElement,
} from "react";
import { Bar } from "react-chartjs-2";

import "./App.css";
Expand Down Expand Up @@ -83,7 +97,10 @@ function App(): ReactElement {
totalNumBytes: 0,
ticks: [],
});
const [config, setConfig] = useState({ runInWorker: true, subscribeNewChannels: false });
const [config, setConfig] = useState({
runInWorker: true,
subscribeNewChannels: false,
});
const [statusLogs, setStatusLogs] = useState<StampedLogEntry[]>([]);

useEffect(() => {
Expand All @@ -99,7 +116,11 @@ function App(): ReactElement {
numMsgs += stats.totalNumMsgs;
numBytes += stats.totalNumBytes;
stats.ticks = [
{ time: now, numMsgs: stats.totalNumMsgs, numBytes: stats.totalNumBytes },
{
time: now,
numMsgs: stats.totalNumMsgs,
numBytes: stats.totalNumBytes,
},
...stats.ticks.slice(0, NUM_TICKS_CHANNEL_STATS - 1),
];
}
Expand Down Expand Up @@ -140,7 +161,7 @@ function App(): ReactElement {
stats.currentSubId = undefined;
}
},
[client],
[client]
);

const subscribeAll = useCallback(
Expand All @@ -149,14 +170,18 @@ function App(): ReactElement {
enableSubscription(id, action);
});
},
[channels, enableSubscription],
[channels, enableSubscription]
);

useEffect(() => {
for (const channel of channels) {
const stats = channelStats.get(channel.id);
if (!stats) {
channelStats.set(channel.id, { totalNumMsgs: 0, totalNumBytes: 0, ticks: [] });
channelStats.set(channel.id, {
totalNumMsgs: 0,
totalNumBytes: 0,
ticks: [],
});
if (config.subscribeNewChannels) {
enableSubscription(channel.id, "subscribe");
}
Expand All @@ -166,9 +191,11 @@ function App(): ReactElement {

const addLogEntry = useCallback(
(entry: LogEntry) => {
setStatusLogs((logs: StampedLogEntry[]) => logs.concat([{ ...entry, time: new Date() }]));
setStatusLogs((logs: StampedLogEntry[]) =>
logs.concat([{ ...entry, time: new Date() }])
);
},
[setStatusLogs],
[setStatusLogs]
);

const connect = useCallback(() => {
Expand Down Expand Up @@ -197,7 +224,11 @@ function App(): ReactElement {
}) as StampedStats[],
});
setStatusLogs([
{ type: "misc", value: `Connection to ${url} established`, time: new Date() },
{
type: "misc",
value: `Connection to ${url} established`,
time: new Date(),
},
]);
});
wsClient.on("close", () => {
Expand All @@ -222,7 +253,7 @@ function App(): ReactElement {
return 1;
}
return 0;
}),
})
);
});
wsClient.on("unadvertise", (removedChannelIds: ChannelId[]) => {
Expand All @@ -234,7 +265,9 @@ function App(): ReactElement {
}
}
setChannels((currChannels: Channel[]) =>
currChannels.filter((channel) => !removedChannelIds.includes(channel.id)),
currChannels.filter(
(channel) => !removedChannelIds.includes(channel.id)
)
);
});
wsClient.on("message", (event: MessageData) => {
Expand All @@ -258,7 +291,9 @@ function App(): ReactElement {
setClient(undefined);
}, [client]);

const totalTicks = totalStats.ticks.filter((v: StampedStats | undefined) => !!v);
const totalTicks = totalStats.ticks.filter(
(v: StampedStats | undefined) => !!v
);
const firstTotalTick = totalTicks[0];
const lastTotalTick = totalTicks[totalTicks.length - 1];
const avgBandWith =
Expand All @@ -272,7 +307,9 @@ function App(): ReactElement {
datasets: [
{
label: "Bandwidth [byte/s]",
data: totalStats.ticks.map((bt) => (bt.byteDiff ?? 0) / (UPDATE_PERIOD_MS / 1000)),
data: totalStats.ticks.map(
(bt) => (bt.byteDiff ?? 0) / (UPDATE_PERIOD_MS / 1000)
),
backgroundColor: "rgba(53, 162, 235, 0.5)",
},
],
Expand Down Expand Up @@ -327,7 +364,10 @@ function App(): ReactElement {
disabled={!!client || typeof Worker === "undefined"}
checked={config.runInWorker}
onChange={(_, checked) => {
setConfig((currConfig) => ({ ...currConfig, runInWorker: checked }));
setConfig((currConfig) => ({
...currConfig,
runInWorker: checked,
}));
}}
/>
}
Expand All @@ -349,8 +389,14 @@ function App(): ReactElement {
/>
</FormGroup>
</Stack>
<Stack direction={{ xs: "row", sm: "column" }} gap={1} justifyContent={"flex-end"}>
<Typography variant="body2">Total msgs: {totalStats.totalNumMsgs}</Typography>
<Stack
direction={{ xs: "row", sm: "column" }}
gap={1}
justifyContent={"flex-end"}
>
<Typography variant="body2">
Total msgs: {totalStats.totalNumMsgs}
</Typography>
<Typography variant="body2">
Total bytes: {totalStats.totalNumBytes.toExponential(1)}
</Typography>
Expand All @@ -359,7 +405,10 @@ function App(): ReactElement {
</Typography>
</Stack>
<div style={{ maxHeight: "150px" }}>
<Bar options={{ ...chartOptions, animation: false }} data={chartData} />
<Bar
options={{ ...chartOptions, animation: false }}
data={chartData}
/>
</div>
</Stack>
<TableContainer component={Paper}>
Expand Down Expand Up @@ -396,9 +445,12 @@ function App(): ReactElement {
const firstTick = ticks[0];
const lastTick = ticks[ticks.length - 1];
if (firstTick != undefined && lastTick != undefined) {
const timeDiffInSec = (firstTick.time - lastTick.time) / 1000;
avgFreq = (firstTick.numMsgs - lastTick.numMsgs) / timeDiffInSec;
avgBw = (firstTick.numBytes - lastTick.numBytes) / timeDiffInSec;
const timeDiffInSec =
(firstTick.time - lastTick.time) / 1000;
avgFreq =
(firstTick.numMsgs - lastTick.numMsgs) / timeDiffInSec;
avgBw =
(firstTick.numBytes - lastTick.numBytes) / timeDiffInSec;
}
return (
<TableRow
Expand All @@ -413,7 +465,10 @@ function App(): ReactElement {
size="small"
checked={stats?.currentSubId != undefined}
onChange={(_, checked) => {
enableSubscription(channel.id, checked ? "subscribe" : "unsubscribe");
enableSubscription(
channel.id,
checked ? "subscribe" : "unsubscribe"
);
}}
/>
</Tooltip>
Expand All @@ -423,17 +478,25 @@ function App(): ReactElement {
scope="row"
>{`${channel.topic} (${channel.id})`}</TableCell>
<TableCell align="right">{channel.schemaName}</TableCell>
<TableCell align="right">{stats?.totalNumMsgs ?? 0}</TableCell>
<TableCell align="right">
{stats?.totalNumMsgs ?? 0}
</TableCell>
<TableCell align="right">
{stats?.totalNumBytes.toExponential(1) ?? 0}
</TableCell>
<TableCell align="right">
{stats?.totalNumBytes != undefined
? (stats.totalNumBytes / stats.totalNumMsgs).toExponential(1)
? (
stats.totalNumBytes / stats.totalNumMsgs
).toExponential(1)
: 0}
</TableCell>
<TableCell align="right">{avgFreq.toFixed(1)} Hz</TableCell>
<TableCell align="right">{avgBw.toExponential(1)} Byte/s</TableCell>
<TableCell align="right">
{avgFreq.toFixed(1)} Hz
</TableCell>
<TableCell align="right">
{avgBw.toExponential(1)} Byte/s
</TableCell>
</TableRow>
);
})}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ const root = ReactDOM.createRoot(document.getElementById("root")!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
</React.StrictMode>
);
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ self.onmessage = (event) => {
});
};
ws.onclose = (wsEvent) => {
send({ type: "close", data: JSON.parse(JSON.stringify(wsEvent) ?? "{}") });
send({
type: "close",
data: JSON.parse(JSON.stringify(wsEvent) ?? "{}"),
});
};
ws.onmessage = (wsEvent) => {
if (wsEvent.data instanceof ArrayBuffer) {
Expand All @@ -38,7 +41,7 @@ self.onmessage = (event) => {
type: "message",
data: wsEvent.data,
},
[wsEvent.data],
[wsEvent.data]
);
} else {
send({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"lib": ["es2020", "dom"],
"jsx": "react-jsx",
"paths": {
"@foxglove/ws-protocol": ["../ws-protocol/src"]
"@foxglove/ws-protocol": ["../typescript/ws-protocol/src"]
}
}
}
File renamed without changes.

0 comments on commit bd960ad

Please sign in to comment.