mirror of
https://github.com/MatrixSeven/file-transfer-go.git
synced 2026-03-19 15:06:00 +08:00
145 lines
4.8 KiB
TypeScript
145 lines
4.8 KiB
TypeScript
import { useCallback, useMemo } from 'react';
|
|
import { useWebRTCStore, type WebRTCStateManager } from '../ui/webRTCStore';
|
|
import { useWebRTCDataChannelManager, WebRTCMessage } from './useWebRTCDataChannelManager';
|
|
import { useWebRTCTrackManager } from './useWebRTCTrackManager';
|
|
import { useWebRTCConnectionCore } from './useWebRTCConnectionCore';
|
|
|
|
// 消息和数据处理器类型
|
|
export type MessageHandler = (message: WebRTCMessage) => void;
|
|
export type DataHandler = (data: ArrayBuffer) => void;
|
|
|
|
// WebRTC 连接接口
|
|
export interface WebRTCConnection {
|
|
// 状态
|
|
isConnected: boolean;
|
|
isConnecting: boolean;
|
|
isWebSocketConnected: boolean;
|
|
isPeerConnected: boolean;
|
|
error: string | null;
|
|
canRetry: boolean;
|
|
|
|
// 操作方法
|
|
connect: (roomCode: string, role: 'sender' | 'receiver') => Promise<void>;
|
|
disconnect: () => void;
|
|
retry: () => Promise<void>;
|
|
sendMessage: (message: WebRTCMessage, channel?: string) => boolean;
|
|
sendData: (data: ArrayBuffer) => boolean;
|
|
|
|
// 处理器注册
|
|
registerMessageHandler: (channel: string, handler: MessageHandler) => () => void;
|
|
registerDataHandler: (channel: string, handler: DataHandler) => () => void;
|
|
|
|
// 工具方法
|
|
getChannelState: () => RTCDataChannelState;
|
|
isConnectedToRoom: (roomCode: string, role: 'sender' | 'receiver') => boolean;
|
|
|
|
// 当前房间信息
|
|
currentRoom: { code: string; role: 'sender' | 'receiver' } | null;
|
|
|
|
// 媒体轨道方法
|
|
addTrack: (track: MediaStreamTrack, stream: MediaStream) => RTCRtpSender | null;
|
|
removeTrack: (sender: RTCRtpSender) => void;
|
|
onTrack: (callback: (event: RTCTrackEvent) => void) => void;
|
|
getPeerConnection: () => RTCPeerConnection | null;
|
|
createOfferNow: () => Promise<boolean>;
|
|
}
|
|
|
|
/**
|
|
* 共享 WebRTC 连接管理器
|
|
* 创建单一的 WebRTC 连接实例,供多个业务模块共享使用
|
|
* 整合所有模块,提供统一的接口
|
|
*/
|
|
export function useSharedWebRTCManager(): WebRTCConnection {
|
|
// 直接从 zustand store 创建状态管理器
|
|
const store = useWebRTCStore();
|
|
const stateManager: WebRTCStateManager = useMemo(() => ({
|
|
getState: () => ({
|
|
isConnected: store.isConnected,
|
|
isConnecting: store.isConnecting,
|
|
isWebSocketConnected: store.isWebSocketConnected,
|
|
isPeerConnected: store.isPeerConnected,
|
|
error: store.error,
|
|
canRetry: store.canRetry,
|
|
currentRoom: store.currentRoom,
|
|
}),
|
|
updateState: store.updateState,
|
|
setCurrentRoom: store.setCurrentRoom,
|
|
resetToInitial: store.resetToInitial,
|
|
isConnectedToRoom: (roomCode: string, role: 'sender' | 'receiver') =>
|
|
store.currentRoom?.code === roomCode &&
|
|
store.currentRoom?.role === role &&
|
|
store.isConnected,
|
|
}), [store]);
|
|
|
|
const dataChannelManager = useWebRTCDataChannelManager(stateManager);
|
|
const trackManager = useWebRTCTrackManager(stateManager);
|
|
const connectionCore = useWebRTCConnectionCore(
|
|
stateManager,
|
|
dataChannelManager,
|
|
trackManager
|
|
);
|
|
|
|
// 从 store 获取当前状态
|
|
const state = {
|
|
isConnected: store.isConnected,
|
|
isConnecting: store.isConnecting,
|
|
isWebSocketConnected: store.isWebSocketConnected,
|
|
isPeerConnected: store.isPeerConnected,
|
|
error: store.error,
|
|
canRetry: store.canRetry,
|
|
};
|
|
|
|
// 创建 createOfferNow 方法
|
|
const createOfferNow = useCallback(async () => {
|
|
const pc = connectionCore.getPeerConnection();
|
|
const ws = connectionCore.getWebSocket();
|
|
if (!pc || !ws) {
|
|
console.error('[SharedWebRTC] PeerConnection 或 WebSocket 不可用');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
return await trackManager.createOfferNow(pc, ws);
|
|
} catch (error) {
|
|
console.error('[SharedWebRTC] 创建 offer 失败:', error);
|
|
return false;
|
|
}
|
|
}, [connectionCore, trackManager]);
|
|
|
|
// 返回统一的接口,保持与当前 API 一致
|
|
return {
|
|
// 状态
|
|
isConnected: state.isConnected,
|
|
isConnecting: state.isConnecting,
|
|
isWebSocketConnected: state.isWebSocketConnected,
|
|
isPeerConnected: state.isPeerConnected,
|
|
error: state.error,
|
|
canRetry: state.canRetry,
|
|
|
|
// 操作方法
|
|
connect: connectionCore.connect,
|
|
disconnect: () => connectionCore.disconnect(true),
|
|
retry: connectionCore.retry,
|
|
sendMessage: dataChannelManager.sendMessage,
|
|
sendData: dataChannelManager.sendData,
|
|
|
|
// 处理器注册
|
|
registerMessageHandler: dataChannelManager.registerMessageHandler,
|
|
registerDataHandler: dataChannelManager.registerDataHandler,
|
|
|
|
// 工具方法
|
|
getChannelState: dataChannelManager.getChannelState,
|
|
isConnectedToRoom: stateManager.isConnectedToRoom,
|
|
|
|
// 媒体轨道方法
|
|
addTrack: trackManager.addTrack,
|
|
removeTrack: trackManager.removeTrack,
|
|
onTrack: trackManager.onTrack,
|
|
getPeerConnection: connectionCore.getPeerConnection,
|
|
createOfferNow,
|
|
|
|
// 当前房间信息
|
|
currentRoom: connectionCore.getCurrentRoom(),
|
|
};
|
|
}
|