Skip to content

Commit

Permalink
[web-pubsub-client/react] Add React hook
Browse files Browse the repository at this point in the history
  • Loading branch information
gfortaine committed Dec 24, 2022
1 parent 061d3d6 commit 6faec6e
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 8 deletions.
31 changes: 26 additions & 5 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion sdk/web-pubsub/web-pubsub-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local",
"check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
"format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist dist-esm test-dist temp types *.tgz *.log",
"clean": "rimraf dist dist-esm dist-test temp types *.tgz *.log",
"execute:samples": "dev-tool samples run samples-dev",
"extract-api": "tsc -p . && api-extractor run --local",
"integration-test:browser": "echo skipped",
Expand Down Expand Up @@ -79,6 +79,7 @@
"@types/jsonwebtoken": "~8.5.0",
"@types/mocha": "^7.0.2",
"@types/node": "^12.0.0",
"@types/react": "^18.0.26",
"@types/sinon": "^9.0.4",
"chai": "^4.2.0",
"cross-env": "^7.0.2",
Expand Down
16 changes: 16 additions & 0 deletions sdk/web-pubsub/web-pubsub-client/review/web-pubsub-client.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ export class WebPubSubClient {
sendEvent(eventName: string, content: JSONTypes | ArrayBuffer, dataType: WebPubSubDataType, options?: SendEventOptions): Promise<WebPubSubResult>;
sendToGroup(groupName: string, content: JSONTypes | ArrayBuffer, dataType: WebPubSubDataType, options?: SendToGroupOptions): Promise<void | WebPubSubResult>;
start(options?: StartOptions): Promise<void>;
// (undocumented)
_state: WebPubSubClientState;
stop(): void;
}

Expand All @@ -274,6 +276,20 @@ export interface WebPubSubClientProtocol {
writeMessage(message: WebPubSubMessage): string | ArrayBuffer;
}

// @public (undocumented)
export enum WebPubSubClientState {
// (undocumented)
Connected = "Connected",
// (undocumented)
Connecting = "Connecting",
// (undocumented)
Disconnected = "Disconnected",
// (undocumented)
Recovering = "Recovering",
// (undocumented)
Stopped = "Stopped"
}

// @public
export type WebPubSubDataType =
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useWebPubSubClient } from "./useWebPubSubClient";
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
GroupDataMessage,
JSONTypes,
OnConnectedArgs,
OnDisconnectedArgs,
OnGroupDataMessageArgs,
OnRestoreGroupFailedArgs as OnRejoinGroupFailedArgs,
OnServerDataMessageArgs,
OnStoppedArgs,
SendToGroupOptions,
WebPubSubClient,
WebPubSubClientProtocol,
WebPubSubClientState,
WebPubSubDataType,
WebPubSubResult,
WebPubSubRetryOptions,
} from "@azure/web-pubsub-client";
import { useEffect, useRef, useState } from "react";

export interface Options {
groupName: string;
protocol?: WebPubSubClientProtocol;
autoReconnect?: boolean;
autoRestoreGroups?: boolean;
messageRetryOptions?: WebPubSubRetryOptions;
reconnectRetryOptions?: WebPubSubRetryOptions;
manual?: boolean;
onConnected?: (args: OnConnectedArgs) => void;
onDisconnected?: (args: OnDisconnectedArgs) => void;
onStopped?: (args: OnStoppedArgs) => void;
onServerMessage?: (args: OnServerDataMessageArgs) => void;
onGroupMessage?: (args: OnGroupDataMessageArgs) => void;
onRejoinGroupFailed?: (args: OnRejoinGroupFailedArgs) => void;
}

export function useWebPubSubClient(
url: string,
{
groupName,
protocol,
autoReconnect,
autoRestoreGroups,
messageRetryOptions,
reconnectRetryOptions,
manual = false,
onConnected,
onDisconnected,
onStopped,
onServerMessage,
onGroupMessage,
onRejoinGroupFailed,
}: Options
) {
const webpubsubclientRef = useRef<WebPubSubClient | null>(null);
const [latestGroupMessage, setLatestGroupMessage] = useState<GroupDataMessage>();
const [connectionStatus, setConnectionStatus] = useState(WebPubSubClientState.Stopped);

async function startWebSocket() {
webpubsubclientRef.current = new WebPubSubClient(url, {
protocol,
autoReconnect,
autoRestoreGroups,
messageRetryOptions,
reconnectRetryOptions,
});

webpubsubclientRef.current.on("connected", (e: OnConnectedArgs) => {
if (typeof onConnected === "function") onConnected(e);
setConnectionStatus(webpubsubclientRef.current?._state!);
});

webpubsubclientRef.current.on("disconnected", (e: OnDisconnectedArgs) => {
if (typeof onDisconnected === "function") onDisconnected(e);
setConnectionStatus(webpubsubclientRef.current?._state!);
});

webpubsubclientRef.current.on("stopped", (e: OnStoppedArgs) => {
if (typeof onStopped === "function") onStopped(e);
setConnectionStatus(webpubsubclientRef.current?._state!);
});

webpubsubclientRef.current.on("server-message", (e: OnServerDataMessageArgs) => {
if (typeof onServerMessage === "function") onServerMessage(e);
});

webpubsubclientRef.current.on("group-message", (e: OnGroupDataMessageArgs) => {
if (typeof onGroupMessage === "function") onGroupMessage(e);
setLatestGroupMessage(e.message);
});

webpubsubclientRef.current.on("rejoin-group-failed", (e: OnRejoinGroupFailedArgs) => {
if (typeof onRejoinGroupFailed === "function") onRejoinGroupFailed(e);
});

await webpubsubclientRef.current.start();
await webpubsubclientRef.current.joinGroup(groupName);
}

const sendMessage = async (
groupName: string,
content: JSONTypes | ArrayBuffer,
dataType: WebPubSubDataType,
options?: SendToGroupOptions
): Promise<void | WebPubSubResult> => {
await webpubsubclientRef.current?.sendToGroup(groupName, content, dataType, options);
};

const connect = () => {
startWebSocket();

setConnectionStatus(webpubsubclientRef.current?._state!);
};

const disconnect = () => webpubsubclientRef.current?.stop();

useEffect(() => {
if (!manual) {
connect();
}

return () => {
disconnect();
};
}, [manual]);

return {
latestGroupMessage,
sendMessage,
connect,
disconnect,
connectionStatus,
ws: webpubsubclientRef.current,
};
}
4 changes: 2 additions & 2 deletions sdk/web-pubsub/web-pubsub-client/src/webPubSubClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { WebPubSubClientCredential } from "./webPubSubClientCredential";
import { WebSocketClientFactory } from "./websocket/websocketClient";
import { WebSocketClientFactoryLike, WebSocketClientLike } from "./websocket/websocketClientLike";

enum WebPubSubClientState {
export enum WebPubSubClientState {
Stopped = "Stopped",
Disconnected = "Disconnected",
Connecting = "Connecting",
Expand All @@ -69,7 +69,7 @@ export class WebPubSubClient {
private readonly _reconnectRetryPolicy: RetryPolicy;

private readonly _emitter: EventEmitter = new EventEmitter();
private _state: WebPubSubClientState;
public _state: WebPubSubClientState;
private _isStopping: boolean = false;
private _ackId: number;

Expand Down

0 comments on commit 6faec6e

Please sign in to comment.