mirror of
https://github.com/MatrixSeven/file-transfer-go.git
synced 2026-05-13 23:07:32 +08:00
feat:自定义turn更新|链接恢复机制|帮助页面添加
This commit is contained in:
231
chuan-next/src/hooks/settings/useIceServersConfig.ts
Normal file
231
chuan-next/src/hooks/settings/useIceServersConfig.ts
Normal file
@@ -0,0 +1,231 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
|
||||
export interface IceServerConfig {
|
||||
id: string;
|
||||
urls: string;
|
||||
username?: string;
|
||||
credential?: string;
|
||||
type: 'stun' | 'turn';
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_ICE_SERVERS: IceServerConfig[] = [
|
||||
{
|
||||
id: 'google-stun-1',
|
||||
urls: 'stun:stun.l.google.com:19302',
|
||||
type: 'stun',
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: 'google-stun-2',
|
||||
urls: 'stun:stun1.l.google.com:19302',
|
||||
type: 'stun',
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: 'google-stun-3',
|
||||
urls: 'stun:stun2.l.google.com:19302',
|
||||
type: 'stun',
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: 'twilio-stun',
|
||||
urls: 'stun:global.stun.twilio.com:3478',
|
||||
type: 'stun',
|
||||
enabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
const STORAGE_KEY = 'webrtc-ice-servers-config';
|
||||
|
||||
export function useIceServersConfig() {
|
||||
const [iceServers, setIceServers] = useState<IceServerConfig[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// 加载配置
|
||||
const loadConfig = useCallback(() => {
|
||||
try {
|
||||
const savedConfig = localStorage.getItem(STORAGE_KEY);
|
||||
if (savedConfig) {
|
||||
const parsed = JSON.parse(savedConfig);
|
||||
setIceServers(parsed);
|
||||
} else {
|
||||
setIceServers(DEFAULT_ICE_SERVERS);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载ICE服务器配置失败:', error);
|
||||
setIceServers(DEFAULT_ICE_SERVERS);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 保存配置
|
||||
const saveConfig = useCallback((servers: IceServerConfig[]) => {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(servers));
|
||||
setIceServers(servers);
|
||||
} catch (error) {
|
||||
console.error('保存ICE服务器配置失败:', error);
|
||||
throw new Error('保存配置失败');
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 添加服务器
|
||||
const addIceServer = useCallback((config: Omit<IceServerConfig, 'id'>) => {
|
||||
const newServer: IceServerConfig = {
|
||||
...config,
|
||||
id: `custom-${Date.now()}`,
|
||||
};
|
||||
const updatedServers = [...iceServers, newServer];
|
||||
saveConfig(updatedServers);
|
||||
}, [iceServers, saveConfig]);
|
||||
|
||||
// 更新服务器
|
||||
const updateIceServer = useCallback((id: string, updates: Partial<IceServerConfig>) => {
|
||||
const updatedServers = iceServers.map(server =>
|
||||
server.id === id ? { ...server, ...updates } : server
|
||||
);
|
||||
saveConfig(updatedServers);
|
||||
}, [iceServers, saveConfig]);
|
||||
|
||||
// 删除服务器
|
||||
const removeIceServer = useCallback((id: string) => {
|
||||
// 确保至少保留一个服务器
|
||||
if (iceServers.length <= 1) {
|
||||
throw new Error('至少需要保留一个ICE服务器');
|
||||
}
|
||||
const updatedServers = iceServers.filter(server => server.id !== id);
|
||||
saveConfig(updatedServers);
|
||||
}, [iceServers, saveConfig]);
|
||||
|
||||
// 恢复默认配置
|
||||
const resetToDefault = useCallback(() => {
|
||||
saveConfig(DEFAULT_ICE_SERVERS);
|
||||
}, [saveConfig]);
|
||||
|
||||
// 获取WebRTC格式的配置
|
||||
const getWebRTCConfig = useCallback((): RTCIceServer[] => {
|
||||
return iceServers
|
||||
.filter(server => server.enabled)
|
||||
.map(server => {
|
||||
const rtcServer: RTCIceServer = {
|
||||
urls: server.urls,
|
||||
};
|
||||
|
||||
if (server.username) {
|
||||
rtcServer.username = server.username;
|
||||
}
|
||||
|
||||
if (server.credential) {
|
||||
rtcServer.credential = server.credential;
|
||||
}
|
||||
|
||||
return rtcServer;
|
||||
});
|
||||
}, [iceServers]);
|
||||
|
||||
// 验证服务器配置
|
||||
const validateServer = useCallback((config: Omit<IceServerConfig, 'id'>) => {
|
||||
const errors: string[] = [];
|
||||
|
||||
if (!config.urls.trim()) {
|
||||
errors.push('服务器地址不能为空');
|
||||
} else {
|
||||
// 基本URL格式验证
|
||||
const urlPattern = /^(stun|turn|turns):.+/i;
|
||||
if (!urlPattern.test(config.urls)) {
|
||||
errors.push('服务器地址格式不正确(应以 stun: 或 turn: 开头)');
|
||||
}
|
||||
}
|
||||
|
||||
if (config.type === 'turn') {
|
||||
if (!config.username?.trim()) {
|
||||
errors.push('TURN服务器需要用户名');
|
||||
}
|
||||
if (!config.credential?.trim()) {
|
||||
errors.push('TURN服务器需要密码');
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}, []);
|
||||
|
||||
// 初始化加载
|
||||
useEffect(() => {
|
||||
loadConfig();
|
||||
}, [loadConfig]);
|
||||
|
||||
return {
|
||||
iceServers,
|
||||
isLoading,
|
||||
addIceServer,
|
||||
updateIceServer,
|
||||
removeIceServer,
|
||||
resetToDefault,
|
||||
getWebRTCConfig,
|
||||
validateServer,
|
||||
saveConfig,
|
||||
};
|
||||
}
|
||||
|
||||
// 独立的函数,用于在非React组件中获取ICE服务器配置
|
||||
export function getIceServersConfig(): RTCIceServer[] {
|
||||
if (typeof window === 'undefined') {
|
||||
// 服务器端默认配置
|
||||
return [
|
||||
{ urls: 'stun:stun.l.google.com:19302' },
|
||||
{ urls: 'stun:stun1.l.google.com:19302' },
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
if (!saved) {
|
||||
// 返回默认配置的WebRTC格式
|
||||
return DEFAULT_ICE_SERVERS
|
||||
.filter(server => server.enabled)
|
||||
.map(server => {
|
||||
const rtcServer: RTCIceServer = {
|
||||
urls: server.urls,
|
||||
};
|
||||
|
||||
if (server.username) {
|
||||
rtcServer.username = server.username;
|
||||
}
|
||||
|
||||
if (server.credential) {
|
||||
rtcServer.credential = server.credential;
|
||||
}
|
||||
|
||||
return rtcServer;
|
||||
});
|
||||
}
|
||||
|
||||
const iceServers: IceServerConfig[] = JSON.parse(saved);
|
||||
return iceServers
|
||||
.filter(server => server.enabled)
|
||||
.map(server => {
|
||||
const rtcServer: RTCIceServer = {
|
||||
urls: server.urls,
|
||||
};
|
||||
|
||||
if (server.username) {
|
||||
rtcServer.username = server.username;
|
||||
}
|
||||
|
||||
if (server.credential) {
|
||||
rtcServer.credential = server.credential;
|
||||
}
|
||||
|
||||
return rtcServer;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取ICE服务器配置失败:', error);
|
||||
// 发生错误时返回默认配置
|
||||
return [
|
||||
{ urls: 'stun:stun.l.google.com:19302' },
|
||||
{ urls: 'stun:stun1.l.google.com:19302' },
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user