Skip to content

Commit

Permalink
Adding subprotocol support
Browse files Browse the repository at this point in the history
Adding API support, TODO: how to capture network or is it needed?

Working

Subprotocol client works
  • Loading branch information
vicancy committed Mar 1, 2024
1 parent 3942f3d commit 6247a92
Show file tree
Hide file tree
Showing 8 changed files with 587 additions and 59 deletions.
3 changes: 3 additions & 0 deletions tools/awps-tunnel/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@azure/web-pubsub-client": "^1.0.0",
"@fluentui/react": "^8.106.3",
"@fluentui/react-components": "^9.34.1",
"@microsoft/signalr": "^8.0.0",
Expand All @@ -16,6 +17,7 @@
"oidc-client": "^1.11.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-highlight": "^0.15.0",
"react-markdown": "^9.0.0",
"react-router-bootstrap": "^0.26.1",
"react-router-dom": "^6.3.0",
Expand Down Expand Up @@ -53,6 +55,7 @@
"@types/node": "^16.18.53",
"@types/react": "^18.2.22",
"@types/react-dom": "^18.2.7",
"@types/react-highlight": "^0.12.8",
"@typescript-eslint/typescript-estree": "^6.12.0",
"ajv": "^8.11.0",
"cross-env": "^7.0.3",
Expand Down
10 changes: 4 additions & 6 deletions tools/awps-tunnel/client/src/panels/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useDataContext } from "../providers/DataContext";
import type { TabValue } from "@fluentui/react-components";
import { Dialog, DialogTrigger, DialogSurface, DialogTitle, DialogBody, DialogContent, Tab, TabList, CompoundButton, MessageBar, MessageBarBody, Button } from "@fluentui/react-components";

import { Dismiss24Regular, Dismiss16Regular, PlugDisconnected24Regular } from "@fluentui/react-icons";
import { Dismiss24Regular, Dismiss16Regular, PlugDisconnected24Regular, PlugDisconnected24Filled } from "@fluentui/react-icons";

import { SimpleClientSection } from "./sections/SimpleClientSection";
import { SubprotocolClientSection } from "./sections/SubprotocolClientSection";
Expand All @@ -21,9 +21,7 @@ export interface ClientPannelProps extends PlaygroundProps {

export interface PlaygroundState {
traffic: TrafficItemProps[];
transferFormat: "text" | "binary" | "json";
message?: string;
subprotocol?: string;
error: string;
}

Expand Down Expand Up @@ -51,13 +49,13 @@ export const Playground = (props: PlaygroundProps) => {
const [url, setUrl] = useState("");
useEffect(() => {
const fetchUrl = async () => {
const newUrl = await dataFetcher.invoke("getClientAccessUrl");
const newUrl = await dataFetcher.invoke("getClientAccessUrl", undefined, undefined, undefined);
setUrl(newUrl);
};
fetchUrl();
const intervalId = setInterval(() => {
fetchUrl();
}, 60 * 10 * 1000); // every 10 minute
}, 60 * 1 * 1000); // every 10 minute

// Clean up the interval on component unmount
return () => clearInterval(intervalId);
Expand All @@ -74,7 +72,7 @@ export const Playground = (props: PlaygroundProps) => {

const availableClients = [
{ icon: <PlugDisconnected24Regular />, title: "WebSocket", id: "websocket", description: "Simple Web PubSub Client" },
// { icon: <PlugDisconnected24Filled />, title: "Web PubSub", id: "webpubsub", description: "Subprotocol Web PubSub Client" }, // TODO: add subprotocol support
{ icon: <PlugDisconnected24Filled />, title: "Web PubSub", id: "webpubsub", description: "Subprotocol Web PubSub Client" }, // TODO: add subprotocol support
// { icon: <Rss24Regular />, title: "MQTT V5", id: "mqtt5", description: "MQTT V5 Client" }, // TODO: add mqtt support
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { ConnectionStatus } from "../../models";
import { MessageBar, MessageBarBody } from "@fluentui/react-components";
import { ClientPannelProps, PlaygroundState } from "../Playground";

interface TrafficItemViewModel {
content: string;
up: boolean;
}
export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps) => {
const transferOptions = [
{ key: "text", text: "Text" },
Expand All @@ -15,12 +19,11 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
const [connected, setConnected] = useState<boolean>(false);
const [showSubprotocol, setShowSubprotocol] = useState(false);
const [subprotocol, setSubprotocol] = useState("");
const [state, setState] = useState<PlaygroundState>({
transferFormat: "json",
message: "",
traffic: [],
error: "",
});
const [traffic, setTraffic] = useState<TrafficItemViewModel[]>([]);
const [message, setMessage] = useState("");
const [error, setError] = useState("");
const [transferFormat, setTransferFormat] = useState<string>("");
const [userId, setUserId] = useState("");

const connectionRef = useRef<WebSocket | null>(null);

Expand All @@ -36,29 +39,21 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
connection.onopen = (event) => {
setConnected(true);
onStatusChange(ConnectionStatus.Connected);
setState((prevState) => ({ ...prevState, connected: true, traffic: [], error: "" }));
setTraffic([]);
setError("");
};
connection.onclose = (event) => {
onStatusChange(ConnectionStatus.Disconnected);
setConnected(false);
setState((prevState) => ({
...prevState,
traffic: [],
error: `WebSocket connection closed with code ${event.code}, reason ${event.reason}.`,
}));
setTraffic([]);
setError(`WebSocket connection closed with code ${event.code}, reason ${event.reason}.`);
};
connection.onmessage = (ev) => {
setState((prevState) => ({
...prevState,
traffic: [{ content: ev.data }, ...prevState.traffic],
}));
setTraffic((e) => [{ content: ev.data, up: false }, ...e]);
};
connectionRef.current = connection;
} catch (e) {
setState((prevState) => ({
...prevState,
error: "Error establishing the WebSocket connection.",
}));
setError("Error establishing the WebSocket connection.");
}
};

Expand All @@ -67,15 +62,11 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
console.error("Connection is not connected");
return;
}
const message = state.message;
if (message) {
connectionRef.current.send(message);
}
setState((prevState) => ({
...prevState,
message: "",
traffic: [{ content: message, up: true }, ...prevState.traffic],
}));
setMessage("");
setTraffic((e) => [{ content: message, up: true }, ...e]);
};
const connectPane = (
<div className="d-flex flex-column websocket-client-container m-2 flex-fill">
Expand All @@ -84,18 +75,18 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
<div>Messages</div>
<Textarea
className="flex-fill"
value={state.message}
value={message}
placeholder="Enter your message here"
onChange={(ev, data) => {
setState((prevState) => ({ ...prevState, message: data.value }));
setMessage(data.value ?? "");
}}
/>
<div className="d-flex justify-content-between">
<Dropdown
defaultSelectedOptions={[transferOptions[0].key]}
placeholder={transferOptions[0].text}
onOptionSelect={(e, d) => {
setState((prevState) => ({ ...prevState, transferFormat: d.optionValue as "text" | "binary" }));
setTransferFormat(d.optionValue as string);
}}
>
{transferOptions.map((option) => (
Expand All @@ -104,13 +95,13 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
</Option>
))}
</Dropdown>
<DefaultButton disabled={!connected || !state.message} text="Send" onClick={send}></DefaultButton>
<DefaultButton disabled={!connected || !message} text="Send" onClick={send}></DefaultButton>
</div>
</div>
)}
</div>
);
const trafficList = state.traffic?.map((i) => TrafficItem(i));
const trafficList = traffic?.map((i) => TrafficItem(i));
const trafficPane = (
<div>
<DetailsList items={trafficList} selectionMode={SelectionMode.none} layoutMode={DetailsListLayoutMode.justified}></DetailsList>
Expand Down Expand Up @@ -156,7 +147,7 @@ export const SimpleClientSection = ({ onStatusChange, url }: ClientPannelProps)
<i>Disconnected</i>
</p>
)}
{state.error && <b className="text-danger">{state.error}</b>}
{error && <b className="text-danger">{error}</b>}
{connected && <ResizablePanel className="flex-fill" left={connectPane} right={trafficPane}></ResizablePanel>}
</>
);
Expand Down
Loading

0 comments on commit 6247a92

Please sign in to comment.