perf: use websocket context

This commit is contained in:
hamster1963 2024-11-24 11:32:42 +08:00
parent 56d6305096
commit 5364d5cdb5
7 changed files with 81 additions and 34 deletions

View File

@ -6,7 +6,6 @@ import { formatNezhaInfo, formatRelativeTime } from "@/lib/utils";
import { NezhaAPI, NezhaAPIResponse } from "@/types/nezha-api";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import useWebSocket from "react-use-websocket";
import {
Area,
AreaChart,
@ -18,6 +17,7 @@ import {
} from "recharts";
import { ServerDetailChartLoading } from "./loading/ServerDetailLoading";
import AnimatedCircularProgressBar from "./ui/animated-circular-progress-bar";
import { useWebSocketContext } from "@/hooks/use-websocket-context";
type cpuChartData = {
timeStamp: string;
@ -54,16 +54,11 @@ type connectChartData = {
export default function ServerDetailChart() {
const { id } = useParams();
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
shouldReconnect: () => true,
reconnectInterval: 3000,
});
const { lastMessage, readyState } = useWebSocketContext();
// 检查连接状态
if (readyState !== 1) {
return (
<ServerDetailChartLoading />
);
return <ServerDetailChartLoading />;
}
// 解析消息

View File

@ -3,24 +3,19 @@ import { ServerDetailLoading } from "@/components/loading/ServerDetailLoading";
import ServerFlag from "@/components/ServerFlag";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { useWebSocketContext } from "@/hooks/use-websocket-context";
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
import { NezhaAPIResponse } from "@/types/nezha-api";
import { useNavigate, useParams } from "react-router-dom";
import useWebSocket from "react-use-websocket";
export default function ServerDetailOverview() {
const navigate = useNavigate();
const { id } = useParams();
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
shouldReconnect: () => true,
reconnectInterval: 3000,
});
const { lastMessage, readyState } = useWebSocketContext();
// 检查连接状态
if (readyState !== 1) {
return (
<ServerDetailLoading />
);
return <ServerDetailLoading />;
}
// 解析消息

View File

@ -0,0 +1,11 @@
import { createContext } from "react";
export interface WebSocketContextType {
sendMessage: (message: string) => void;
lastMessage: MessageEvent | null;
readyState: number;
}
export const WebSocketContext = createContext<WebSocketContextType | undefined>(
undefined,
);

View File

@ -0,0 +1,34 @@
import React from "react";
import {
WebSocketContext,
type WebSocketContextType,
} from "./websocket-context";
import useWebSocket from "react-use-websocket";
interface WebSocketProviderProps {
url: string;
children: React.ReactNode;
}
export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
url,
children,
}) => {
const { sendMessage, lastMessage, readyState } = useWebSocket(url, {
reconnectAttempts: 10,
reconnectInterval: 3000,
shouldReconnect: () => true,
});
const contextValue: WebSocketContextType = {
sendMessage,
lastMessage,
readyState,
};
return (
<WebSocketContext.Provider value={contextValue}>
{children}
</WebSocketContext.Provider>
);
};

View File

@ -0,0 +1,12 @@
import { useContext } from "react";
import { WebSocketContext } from "../context/websocket-context";
export const useWebSocketContext = () => {
const context = useContext(WebSocketContext);
if (context === undefined) {
throw new Error(
"useWebSocketContext must be used within a WebSocketProvider",
);
}
return context;
};

View File

@ -7,6 +7,7 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Toaster } from "sonner";
import { MotionProvider } from "./components/motion/motion-provider";
import { WebSocketProvider } from "./context/websocket-provider";
const queryClient = new QueryClient();
@ -15,6 +16,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<MotionProvider>
<ThemeProvider storageKey="vite-ui-theme">
<QueryClientProvider client={queryClient}>
<WebSocketProvider url="/api/v1/ws/server">
<App />
<Toaster
duration={1000}
@ -28,6 +30,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
className={"flex items-center justify-center"}
/>
<ReactQueryDevtools />
</WebSocketProvider>
</QueryClientProvider>
</ThemeProvider>
</MotionProvider>

View File

@ -1,4 +1,3 @@
import useWebSocket from "react-use-websocket";
import { NezhaAPIResponse } from "@/types/nezha-api";
import ServerCard from "@/components/ServerCard";
import { formatNezhaInfo } from "@/lib/utils";
@ -9,16 +8,14 @@ import { useQuery } from "@tanstack/react-query";
import { fetchServerGroup } from "@/lib/nezha-api";
import GroupSwitch from "@/components/GroupSwitch";
import { ServerGroup } from "@/types/nezha-api";
import { useWebSocketContext } from "@/hooks/use-websocket-context";
export default function Servers() {
const { data: groupData } = useQuery({
queryKey: ["server-group"],
queryFn: () => fetchServerGroup(),
});
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
shouldReconnect: () => true,
reconnectInterval: 3000,
});
const { lastMessage, readyState } = useWebSocketContext();
// 添加分组状态
const [currentGroup, setCurrentGroup] = useState<string>("All");