mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 09:31:55 +08:00
fix: websocket proxy
This commit is contained in:
parent
1bda0cc3b7
commit
d1558b71c4
@ -3,7 +3,6 @@ import { useState, useEffect, useRef, useCallback } from "react";
|
||||
export interface WebSocketHook {
|
||||
socket: WebSocket | null;
|
||||
connected: boolean;
|
||||
onlineCount: number;
|
||||
message: string | null;
|
||||
sendMessage: (msg: string) => void;
|
||||
}
|
||||
@ -12,7 +11,6 @@ export default function useWebSocket(url: string): WebSocketHook {
|
||||
const [socket, setSocket] = useState<WebSocket | null>(null);
|
||||
const [message, setMessage] = useState<string | null>(null);
|
||||
const [connected, setConnected] = useState<boolean>(false);
|
||||
const [onlineCount, setOnlineCount] = useState<number>(0);
|
||||
const socketRef = useRef<WebSocket | null>(null);
|
||||
const reconnectAttempts = useRef<number>(0);
|
||||
const reconnectTimeout = useRef<NodeJS.Timeout | null>(null);
|
||||
@ -32,28 +30,37 @@ export default function useWebSocket(url: string): WebSocketHook {
|
||||
|
||||
ws.onmessage = (event: MessageEvent) => {
|
||||
setMessage(event.data);
|
||||
const msgJson = JSON.parse(event.data);
|
||||
if (msgJson.type === "live") {
|
||||
setOnlineCount(msgJson.data.count);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error("WebSocket Error:", error);
|
||||
// 在错误发生时主动关闭连接,触发重连
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
setConnected(false);
|
||||
// 清理当前的 socket
|
||||
socketRef.current = null;
|
||||
|
||||
if (!isUnmounted.current) {
|
||||
// Attempt to reconnect
|
||||
if (reconnectAttempts.current < 5) {
|
||||
const timeout = Math.pow(2, reconnectAttempts.current) * 1000; // Exponential backoff
|
||||
// 检查是否已经在重连中
|
||||
if (reconnectTimeout.current) {
|
||||
clearTimeout(reconnectTimeout.current);
|
||||
}
|
||||
|
||||
// Attempt to reconnect with increased max attempts
|
||||
if (reconnectAttempts.current < 10) {
|
||||
const timeout = Math.min(Math.pow(2, reconnectAttempts.current) * 1000, 30000); // 最大30秒
|
||||
reconnectAttempts.current += 1;
|
||||
console.log(`Attempting to reconnect in ${timeout/1000} seconds...`);
|
||||
reconnectTimeout.current = setTimeout(() => {
|
||||
connect();
|
||||
}, timeout);
|
||||
} else {
|
||||
console.warn("Max reconnect attempts reached.");
|
||||
console.warn("Max reconnect attempts reached. Please refresh the page to try again.");
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -85,5 +92,5 @@ export default function useWebSocket(url: string): WebSocketHook {
|
||||
}
|
||||
}, []);
|
||||
|
||||
return { socket, message, sendMessage, connected, onlineCount };
|
||||
return { socket, message, sendMessage, connected };
|
||||
}
|
14
src/lib/websocketContext.tsx
Normal file
14
src/lib/websocketContext.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { createContext, useContext } from "react";
|
||||
import { WebSocketHook } from "../hooks/use-websocket";
|
||||
|
||||
export const WebSocketContext = createContext<WebSocketHook | undefined>(undefined);
|
||||
|
||||
export const useWebSocketContext = (): WebSocketHook => {
|
||||
const context = useContext(WebSocketContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useWebSocketContext must be used within a WebSocketProvider",
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
@ -1,25 +1,14 @@
|
||||
import { createContext, useContext, ReactNode } from "react";
|
||||
import useWebSocket, { WebSocketHook } from "./useWebsocket";
|
||||
import { ReactNode } from "react";
|
||||
import useWebSocket from "../hooks/use-websocket";
|
||||
import { WebSocketContext } from "./websocketContext";
|
||||
|
||||
interface WebSocketProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const WebSocketContext = createContext<WebSocketHook | undefined>(undefined);
|
||||
|
||||
export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
|
||||
const ws = useWebSocket("wss://dev-next.buycoffee.top:4433/api/v1/ws/server");
|
||||
const ws = useWebSocket('/api/v1/ws/server');
|
||||
return (
|
||||
<WebSocketContext.Provider value={ws}>{children}</WebSocketContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useWebSocketContext = (): WebSocketHook => {
|
||||
const context = useContext(WebSocketContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useWebSocketContext must be used within a WebSocketProvider",
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
@ -1,4 +1,20 @@
|
||||
import { useWebSocketContext } from "@/lib/websocketContext";
|
||||
import { NezhaAPI } from "@/types/nezha-api";
|
||||
|
||||
|
||||
export default function Servers() {
|
||||
const { connected, message } = useWebSocketContext()
|
||||
|
||||
if (!connected || !message) {
|
||||
return (
|
||||
<p>连接中...</p>
|
||||
)
|
||||
}
|
||||
|
||||
const nezhaWsData = JSON.parse(message) as NezhaAPI[]
|
||||
|
||||
console.log(nezhaWsData)
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-5xl px-4 lg:px-0">
|
||||
<div className="flex justify-between mb-4 mt-4 items-center">
|
||||
|
@ -10,4 +10,13 @@ export default defineConfig({
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/api/v1/ws': {
|
||||
target: 'http://localhost:8008',
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user