修復 too many connection 問題

This commit is contained in:
2025-09-21 02:46:16 +08:00
parent a36ab3c98d
commit 808d5bb52c
36 changed files with 5582 additions and 249 deletions

297
app/auto-ip-test/page.tsx Normal file
View File

@@ -0,0 +1,297 @@
'use client';
import React, { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Loader2, Database, CheckCircle, AlertTriangle, RefreshCw, Trash2 } from 'lucide-react';
interface IPDetectionResult {
detectedIP: string;
confidence: 'high' | 'medium' | 'low';
source: string;
isPublicIP: boolean;
allCandidates: string[];
}
interface ConnectionStatus {
ip: string;
connectionCount: number;
connections: any[];
}
export default function AutoIPTestPage() {
const [ipDetection, setIpDetection] = useState<IPDetectionResult | null>(null);
const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus | null>(null);
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState<string>('');
const [error, setError] = useState<string>('');
// 自動偵測 IP
const detectIP = async () => {
try {
setLoading(true);
const response = await fetch('/api/debug-ip');
const data = await response.json();
if (data.success && data.data.smartDetection) {
setIpDetection(data.data.smartDetection);
setMessage(`IP 偵測成功: ${data.data.smartDetection.detectedIP}`);
setError('');
} else {
setError('IP 偵測失敗');
}
} catch (err) {
setError('IP 偵測錯誤: ' + (err instanceof Error ? err.message : '未知錯誤'));
} finally {
setLoading(false);
}
};
// 獲取連線狀態
const getConnectionStatus = async () => {
try {
setLoading(true);
const response = await fetch('/api/ip-cleanup?action=status');
const data = await response.json();
if (data.success) {
setConnectionStatus(data.data);
setMessage(`連線狀態獲取成功: ${data.data.connectionCount} 個連線`);
setError('');
} else {
setError('獲取連線狀態失敗');
}
} catch (err) {
setError('獲取連線狀態錯誤: ' + (err instanceof Error ? err.message : '未知錯誤'));
} finally {
setLoading(false);
}
};
// 清理當前 IP 連線
const cleanupConnections = async () => {
try {
setLoading(true);
const response = await fetch('/api/ip-cleanup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ action: 'cleanup-current' }),
});
const data = await response.json();
if (data.success) {
setMessage(`清理成功: ${data.message}`);
setError('');
// 重新獲取連線狀態
await getConnectionStatus();
} else {
setError(data.error || '清理失敗');
}
} catch (err) {
setError('清理錯誤: ' + (err instanceof Error ? err.message : '未知錯誤'));
} finally {
setLoading(false);
}
};
// 組件載入時自動偵測
useEffect(() => {
detectIP();
}, []);
return (
<div className="container mx-auto p-6 space-y-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold"> IP </h1>
<p className="text-muted-foreground">
IP
</p>
</div>
<div className="flex gap-2">
<Button
onClick={detectIP}
disabled={loading}
variant="outline"
>
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />}
IP
</Button>
<Button
onClick={getConnectionStatus}
disabled={loading}
variant="outline"
>
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Database className="h-4 w-4" />}
</Button>
</div>
</div>
{/* IP 偵測結果 */}
{ipDetection && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<CheckCircle className="h-5 w-5" />
IP
</CardTitle>
<CardDescription>
IP
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center gap-4">
<Badge
variant={ipDetection.isPublicIP ? "default" : "secondary"}
className="text-lg px-3 py-1"
>
{ipDetection.detectedIP}
</Badge>
<Badge
variant={
ipDetection.confidence === 'high' ? "default" :
ipDetection.confidence === 'medium' ? "secondary" : "destructive"
}
className="text-lg px-3 py-1"
>
: {ipDetection.confidence}
</Badge>
<Badge variant="outline" className="text-lg px-3 py-1">
: {ipDetection.source}
</Badge>
</div>
{ipDetection.allCandidates.length > 1 && (
<div>
<p className="text-sm font-medium mb-2"> IP:</p>
<div className="flex flex-wrap gap-2">
{ipDetection.allCandidates.map((ip, index) => (
<Badge
key={index}
variant={ip === ipDetection.detectedIP ? "default" : "outline"}
className="text-sm"
>
{ip}
</Badge>
))}
</div>
</div>
)}
</CardContent>
</Card>
)}
{/* 連線狀態 */}
{connectionStatus && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Database className="h-5 w-5" />
</CardTitle>
<CardDescription>
IP
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center gap-4">
<Badge variant="default" className="text-lg px-3 py-1">
IP: {connectionStatus.ip}
</Badge>
<Badge
variant={connectionStatus.connectionCount > 0 ? "destructive" : "default"}
className="text-lg px-3 py-1"
>
: {connectionStatus.connectionCount}
</Badge>
</div>
{connectionStatus.connections.length > 0 && (
<div>
<p className="text-sm font-medium mb-2">:</p>
<div className="space-y-2 max-h-48 overflow-y-auto">
{connectionStatus.connections.map((conn, index) => (
<div key={index} className="flex items-center justify-between p-2 border rounded text-sm">
<span>ID: {conn.ID}</span>
<span>HOST: {conn.HOST}</span>
<span>: {conn.TIME}s</span>
<span>: {conn.STATE || 'Sleep'}</span>
</div>
))}
</div>
</div>
)}
</CardContent>
</Card>
)}
{/* 操作按鈕 */}
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
IP
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex gap-4">
<Button
onClick={cleanupConnections}
disabled={loading || !ipDetection}
variant="destructive"
className="flex-1"
>
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
</Button>
<Button
onClick={getConnectionStatus}
disabled={loading}
variant="outline"
className="flex-1"
>
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />}
</Button>
</div>
</CardContent>
</Card>
{/* 使用說明 */}
<Card>
<CardHeader>
<CardTitle>使</CardTitle>
</CardHeader>
<CardContent className="space-y-2 text-sm text-muted-foreground">
<p> <strong>:</strong> IP </p>
<p> <strong>:</strong> 使 IP </p>
<p> <strong>:</strong> IP </p>
<p> <strong>:</strong> IP </p>
<p> <strong>:</strong> </p>
</CardContent>
</Card>
{/* 訊息顯示 */}
{message && (
<Alert>
<CheckCircle className="h-4 w-4" />
<AlertDescription>{message}</AlertDescription>
</Alert>
)}
{error && (
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
</div>
);
}