mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 17:41:56 +08:00
perf: use websocket context
This commit is contained in:
parent
56d6305096
commit
5364d5cdb5
@ -6,7 +6,6 @@ import { formatNezhaInfo, formatRelativeTime } from "@/lib/utils";
|
|||||||
import { NezhaAPI, NezhaAPIResponse } from "@/types/nezha-api";
|
import { NezhaAPI, NezhaAPIResponse } from "@/types/nezha-api";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import useWebSocket from "react-use-websocket";
|
|
||||||
import {
|
import {
|
||||||
Area,
|
Area,
|
||||||
AreaChart,
|
AreaChart,
|
||||||
@ -18,6 +17,7 @@ import {
|
|||||||
} from "recharts";
|
} from "recharts";
|
||||||
import { ServerDetailChartLoading } from "./loading/ServerDetailLoading";
|
import { ServerDetailChartLoading } from "./loading/ServerDetailLoading";
|
||||||
import AnimatedCircularProgressBar from "./ui/animated-circular-progress-bar";
|
import AnimatedCircularProgressBar from "./ui/animated-circular-progress-bar";
|
||||||
|
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
||||||
|
|
||||||
type cpuChartData = {
|
type cpuChartData = {
|
||||||
timeStamp: string;
|
timeStamp: string;
|
||||||
@ -54,16 +54,11 @@ type connectChartData = {
|
|||||||
|
|
||||||
export default function ServerDetailChart() {
|
export default function ServerDetailChart() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
|
const { lastMessage, readyState } = useWebSocketContext();
|
||||||
shouldReconnect: () => true,
|
|
||||||
reconnectInterval: 3000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查连接状态
|
// 检查连接状态
|
||||||
if (readyState !== 1) {
|
if (readyState !== 1) {
|
||||||
return (
|
return <ServerDetailChartLoading />;
|
||||||
<ServerDetailChartLoading />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析消息
|
// 解析消息
|
||||||
|
@ -3,24 +3,19 @@ import { ServerDetailLoading } from "@/components/loading/ServerDetailLoading";
|
|||||||
import ServerFlag from "@/components/ServerFlag";
|
import ServerFlag from "@/components/ServerFlag";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
||||||
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
|
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
|
||||||
import { NezhaAPIResponse } from "@/types/nezha-api";
|
import { NezhaAPIResponse } from "@/types/nezha-api";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import useWebSocket from "react-use-websocket";
|
|
||||||
|
|
||||||
export default function ServerDetailOverview() {
|
export default function ServerDetailOverview() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
|
const { lastMessage, readyState } = useWebSocketContext();
|
||||||
shouldReconnect: () => true,
|
|
||||||
reconnectInterval: 3000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查连接状态
|
// 检查连接状态
|
||||||
if (readyState !== 1) {
|
if (readyState !== 1) {
|
||||||
return (
|
return <ServerDetailLoading />;
|
||||||
<ServerDetailLoading />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析消息
|
// 解析消息
|
||||||
|
11
src/context/websocket-context.ts
Normal file
11
src/context/websocket-context.ts
Normal 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,
|
||||||
|
);
|
34
src/context/websocket-provider.tsx
Normal file
34
src/context/websocket-provider.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
12
src/hooks/use-websocket-context.ts
Normal file
12
src/hooks/use-websocket-context.ts
Normal 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;
|
||||||
|
};
|
@ -7,6 +7,7 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
|||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { Toaster } from "sonner";
|
import { Toaster } from "sonner";
|
||||||
import { MotionProvider } from "./components/motion/motion-provider";
|
import { MotionProvider } from "./components/motion/motion-provider";
|
||||||
|
import { WebSocketProvider } from "./context/websocket-provider";
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|||||||
<MotionProvider>
|
<MotionProvider>
|
||||||
<ThemeProvider storageKey="vite-ui-theme">
|
<ThemeProvider storageKey="vite-ui-theme">
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<WebSocketProvider url="/api/v1/ws/server">
|
||||||
<App />
|
<App />
|
||||||
<Toaster
|
<Toaster
|
||||||
duration={1000}
|
duration={1000}
|
||||||
@ -28,6 +30,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|||||||
className={"flex items-center justify-center"}
|
className={"flex items-center justify-center"}
|
||||||
/>
|
/>
|
||||||
<ReactQueryDevtools />
|
<ReactQueryDevtools />
|
||||||
|
</WebSocketProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</MotionProvider>
|
</MotionProvider>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import useWebSocket from "react-use-websocket";
|
|
||||||
import { NezhaAPIResponse } from "@/types/nezha-api";
|
import { NezhaAPIResponse } from "@/types/nezha-api";
|
||||||
import ServerCard from "@/components/ServerCard";
|
import ServerCard from "@/components/ServerCard";
|
||||||
import { formatNezhaInfo } from "@/lib/utils";
|
import { formatNezhaInfo } from "@/lib/utils";
|
||||||
@ -9,16 +8,14 @@ import { useQuery } from "@tanstack/react-query";
|
|||||||
import { fetchServerGroup } from "@/lib/nezha-api";
|
import { fetchServerGroup } from "@/lib/nezha-api";
|
||||||
import GroupSwitch from "@/components/GroupSwitch";
|
import GroupSwitch from "@/components/GroupSwitch";
|
||||||
import { ServerGroup } from "@/types/nezha-api";
|
import { ServerGroup } from "@/types/nezha-api";
|
||||||
|
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
||||||
|
|
||||||
export default function Servers() {
|
export default function Servers() {
|
||||||
const { data: groupData } = useQuery({
|
const { data: groupData } = useQuery({
|
||||||
queryKey: ["server-group"],
|
queryKey: ["server-group"],
|
||||||
queryFn: () => fetchServerGroup(),
|
queryFn: () => fetchServerGroup(),
|
||||||
});
|
});
|
||||||
const { lastMessage, readyState } = useWebSocket("/api/v1/ws/server", {
|
const { lastMessage, readyState } = useWebSocketContext();
|
||||||
shouldReconnect: () => true,
|
|
||||||
reconnectInterval: 3000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 添加分组状态
|
// 添加分组状态
|
||||||
const [currentGroup, setCurrentGroup] = useState<string>("All");
|
const [currentGroup, setCurrentGroup] = useState<string>("All");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user