@blocklet/payment-react
Version:
Reusable react components for payment kit v2
56 lines (55 loc) • 1.95 kB
JavaScript
import { WsClient } from "@arcblock/ws";
import get from "lodash/get";
import { useEffect, useRef } from "react";
const RELAY_SOCKET_PREFIX = "/.well-known/service/relay";
const getAppId = () => get(window, "blocklet.appPid") || get(window, "blocklet.appId") || "";
const getRelayChannel = (token) => `relay:${getAppId()}:${token}`;
const getRelayProtocol = () => window.location.protocol === "https:" ? "wss:" : "ws:";
const getSocketHost = () => new URL(window.location.href).host;
export function useSubscription(channel) {
const socket = useRef(null);
const subscription = useRef(null);
useEffect(() => {
if (getAppId()) {
const needReconnect = !socket.current || socket.current.isConnected() === false;
if (needReconnect) {
socket.current = new WsClient(`${getRelayProtocol()}//${getSocketHost()}${RELAY_SOCKET_PREFIX}`, {
longpollerTimeout: 5e3,
// connection timeout
heartbeatIntervalMs: 30 * 1e3
});
socket.current.connect();
}
}
return () => {
if (socket.current) {
socket.current.disconnect();
socket.current = null;
}
};
}, []);
useEffect(() => {
if (channel) {
let needSubscription = false;
if (subscription.current) {
if (subscription.current.channel !== channel) {
socket.current?.unsubscribe(getRelayChannel(subscription.current.channel));
needSubscription = true;
}
} else {
needSubscription = true;
}
if (needSubscription && socket.current) {
subscription.current = socket.current.subscribe(getRelayChannel(channel));
subscription.current.channel = channel;
}
}
return () => {
if (subscription.current) {
socket.current?.unsubscribe(getRelayChannel(subscription.current.channel));
subscription.current = null;
}
};
}, [channel]);
return subscription.current;
}