mirror of
https://github.com/MatrixSeven/file-transfer-go.git
synced 2026-02-04 03:25:03 +08:00
feat:处理组件渲染导致重复注册事件文件
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import { useSharedWebRTCManager } from '@/hooks/webrtc/useSharedWebRTCManager';
|
||||
import { useFileTransferBusiness } from '@/hooks/webrtc/useFileTransferBusiness';
|
||||
@@ -42,8 +42,9 @@ export const WebRTCFileTransfer: React.FC = () => {
|
||||
const urlProcessedRef = useRef(false); // 使用 ref 防止重复处理 URL
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
// 创建共享连接
|
||||
// 创建共享连接 - 使用 useMemo 稳定引用
|
||||
const connection = useSharedWebRTCManager();
|
||||
const stableConnection = useMemo(() => connection, [connection.isConnected, connection.isConnecting, connection.isWebSocketConnected, connection.error]);
|
||||
|
||||
// 使用共享连接创建业务层
|
||||
const {
|
||||
@@ -60,7 +61,7 @@ export const WebRTCFileTransfer: React.FC = () => {
|
||||
onFileListReceived,
|
||||
onFileRequested,
|
||||
onFileProgress
|
||||
} = useFileTransferBusiness(connection);
|
||||
} = useFileTransferBusiness(stableConnection);
|
||||
|
||||
// 加入房间 (接收模式) - 提前定义以供 useEffect 使用
|
||||
const joinRoom = useCallback(async (code: string) => {
|
||||
|
||||
@@ -342,7 +342,7 @@ export function useFileTransferBusiness(connection: WebRTCConnection) {
|
||||
}
|
||||
}, [updateState, connection]);
|
||||
|
||||
// 设置处理器
|
||||
// 设置处理器 - 使用稳定的引用避免反复注册
|
||||
useEffect(() => {
|
||||
// 使用共享连接的注册方式
|
||||
const unregisterMessage = connection.registerMessageHandler(CHANNEL_NAME, handleMessage);
|
||||
@@ -352,7 +352,7 @@ export function useFileTransferBusiness(connection: WebRTCConnection) {
|
||||
unregisterMessage();
|
||||
unregisterData();
|
||||
};
|
||||
}, [handleMessage, handleData]);
|
||||
}, [connection]); // 只依赖 connection 对象,不依赖处理函数
|
||||
|
||||
// 监听连接状态变化 (直接使用 connection 的状态)
|
||||
useEffect(() => {
|
||||
@@ -564,22 +564,27 @@ export function useFileTransferBusiness(connection: WebRTCConnection) {
|
||||
|
||||
// 发送文件列表
|
||||
const sendFileList = useCallback((fileList: FileInfo[]) => {
|
||||
if (!connection.isPeerConnected) {
|
||||
// 检查连接状态 - 优先检查数据通道状态,因为 P2P 连接可能已经建立但状态未及时更新
|
||||
const channelState = connection.getChannelState();
|
||||
const peerConnected = connection.isPeerConnected;
|
||||
|
||||
console.log('发送文件列表检查:', {
|
||||
channelState,
|
||||
peerConnected,
|
||||
fileListLength: fileList.length
|
||||
});
|
||||
|
||||
// 如果数据通道已打开或者 P2P 已连接,就可以发送文件列表
|
||||
if (channelState === 'open' || peerConnected) {
|
||||
console.log('发送文件列表:', fileList);
|
||||
|
||||
connection.sendMessage({
|
||||
type: 'file-list',
|
||||
payload: fileList
|
||||
}, CHANNEL_NAME);
|
||||
} else {
|
||||
console.log('P2P连接未建立,等待连接后再发送文件列表');
|
||||
return;
|
||||
}
|
||||
|
||||
if (connection.getChannelState() !== 'open') {
|
||||
console.error('数据通道未准备就绪,无法发送文件列表');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('发送文件列表:', fileList);
|
||||
|
||||
connection.sendMessage({
|
||||
type: 'file-list',
|
||||
payload: fileList
|
||||
}, CHANNEL_NAME);
|
||||
}, [connection]);
|
||||
|
||||
// 请求文件
|
||||
|
||||
@@ -289,11 +289,25 @@ export function useSharedWebRTCManager(): WebRTCConnection {
|
||||
|
||||
case 'answer':
|
||||
console.log('[SharedWebRTC] 📬 处理answer...');
|
||||
if (pc.signalingState === 'have-local-offer') {
|
||||
await pc.setRemoteDescription(new RTCSessionDescription(message.payload));
|
||||
console.log('[SharedWebRTC] ✅ answer 处理完成');
|
||||
} else {
|
||||
console.warn('[SharedWebRTC] ⚠️ PeerConnection状态不是have-local-offer:', pc.signalingState);
|
||||
try {
|
||||
if (pc.signalingState === 'have-local-offer') {
|
||||
await pc.setRemoteDescription(new RTCSessionDescription(message.payload));
|
||||
console.log('[SharedWebRTC] ✅ answer 处理完成');
|
||||
} else {
|
||||
console.warn('[SharedWebRTC] ⚠️ PeerConnection状态不是have-local-offer:', pc.signalingState);
|
||||
// 如果状态不对,尝试重新创建 offer
|
||||
if (pc.connectionState === 'connected' || pc.connectionState === 'connecting') {
|
||||
console.log('[SharedWebRTC] 🔄 连接状态正常但信令状态异常,尝试重新创建offer');
|
||||
// 这里不直接处理,让连接自然建立
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[SharedWebRTC] ❌ 处理answer失败:', error);
|
||||
if (error instanceof Error && error.message.includes('Failed to set local answer sdp')) {
|
||||
console.warn('[SharedWebRTC] ⚠️ Answer处理失败,可能是连接状态变化导致的');
|
||||
// 清理连接状态,让客户端重新连接
|
||||
updateState({ error: 'WebRTC连接状态异常,请重新连接', isPeerConnected: false });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user