From ab57303eb6c2e8275eb063e1527959fc91cfcb95 Mon Sep 17 00:00:00 2001 From: RoyceDa Date: Sun, 15 Mar 2026 17:22:48 +0200 Subject: [PATCH] =?UTF-8?q?=D0=91=D1=83=D1=84=D0=B5=D1=80=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20ICE=20=D0=BA=D0=B0=D0=BD=D0=B4=D0=B8?= =?UTF-8?q?=D0=B4=D0=B0=D1=82=D0=BE=D0=B2=20(=D0=B4=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=B7=D0=B1=D0=B5=D0=B6=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B3=D0=BE?= =?UTF-8?q?=D0=BD=D0=BA=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/providers/CallProvider/CallProvider.tsx | 67 ++++++++++++++++++--- app/servers.ts | 4 +- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/app/providers/CallProvider/CallProvider.tsx b/app/providers/CallProvider/CallProvider.tsx index 8f2dd7f..0e30063 100644 --- a/app/providers/CallProvider/CallProvider.tsx +++ b/app/providers/CallProvider/CallProvider.tsx @@ -71,15 +71,40 @@ export function CallProvider(props : CallProviderProps) { const roleRef = useRef(null); const [sharedSecret, setSharedSecret] = useState(""); const iceServersRef = useRef([]); + const remoteAudioRef = useRef(null); + const iceCandidatesBufferRef = useRef([]); useEffect(() => { - /** + /** * Нам нужно получить ICE серверы для установки соединения из разных сетей * Получаем их от сервера */ let packet = new PacketIceServers(); send(packet); - }, []); + + //debug + + setInterval(async () => { + if(callState == CallState.ACTIVE){ + if(peerConnectionRef.current){ + const stats = await peerConnectionRef.current.getStats(); + stats.forEach((report) => { + + if (report.type === "inbound-rtp" && !report.isRemote) { + const kind = (report as any).kind || (report as any).mediaType; + const bytesReceived = (report as any).bytesReceived ?? 0; + const packetsReceived = (report as any).packetsReceived ?? 0; + const packetsLost = (report as any).packetsLost ?? 0; + + console.log( + `[inbound ${kind}] bytesReceived=${bytesReceived}, packetsReceived=${packetsReceived}, packetsLost=${packetsLost}` + ); + } + }); + } + } + }, 2000); + }, [callState, peerConnectionRef]); usePacket(28, async (packet: PacketIceServers) => { let iceServers = packet.getIceServers(); @@ -118,6 +143,15 @@ export function CallProvider(props : CallProviderProps) { */ const sdp = JSON.parse(packet.getSdpOrCandidate()); await peerConnectionRef.current?.setRemoteDescription(new RTCSessionDescription(sdp)); + if(iceCandidatesBufferRef.current.length > 0){ + /** + * У нас есть буферизированные ICE кандидаты, которые мы получили до установки удаленного описания, теперь мы можем их добавить в PeerConnection + */ + for(let i = 0; i < iceCandidatesBufferRef.current.length; i++){ + await peerConnectionRef.current?.addIceCandidate(iceCandidatesBufferRef.current[i]); + } + iceCandidatesBufferRef.current = []; + } info("Received WebRTC answer and set remote description"); return; } @@ -127,6 +161,14 @@ export function CallProvider(props : CallProviderProps) { */ const candidate = JSON.parse(packet.getSdpOrCandidate()); console.info(candidate); + if(peerConnectionRef.current?.remoteDescription == null){ + /** + * Удаленное описание еще не установлено, буферизуем кандидата, чтобы добавить его после установки удаленного описания + */ + iceCandidatesBufferRef.current.push(new RTCIceCandidate(candidate)); + info("Received WebRTC ICE candidate but remote description is not set yet, buffering candidate"); + return; + } await peerConnectionRef.current?.addIceCandidate(new RTCIceCandidate(candidate)); info("Received WebRTC ICE candidate and added to peer connection"); return; @@ -165,13 +207,7 @@ export function CallProvider(props : CallProviderProps) { /** * Сбросили звонок */ - setActiveCall(""); - setCallState(CallState.ENDED); - setShowCallView(false); - setSessionKeys(null); - setSharedSecret(""); - setDuration(0); - roleRef.current = null; + end(); return; } if(signalType == SignalType.CALL){ @@ -276,7 +312,12 @@ export function CallProvider(props : CallProviderProps) { * При получении медиа-трека с другой стороны */ console.info("TRACK RECV!!!!!"); + if(remoteAudioRef.current){ + console.info(event.streams); + remoteAudioRef.current.srcObject = event.streams[0]; + } } + /** * Запрашиваем Аудио поток с микрофона и добавляем его в PeerConnection, чтобы другая сторона могла его получить и воспроизвести, * когда мы установим WebRTC соединение @@ -291,7 +332,7 @@ export function CallProvider(props : CallProviderProps) { * Отправляем свой оффер другой стороне */ let offer = await peerConnectionRef.current.createOffer(); - peerConnectionRef.current.setLocalDescription(offer); + await peerConnectionRef.current.setLocalDescription(offer); let offerSignal = new PacketWebRTC(); offerSignal.setSignalType(WebRTCSignalType.OFFER); offerSignal.setSdpOrCandidate(JSON.stringify(offer)); @@ -325,6 +366,11 @@ export function CallProvider(props : CallProviderProps) { packetSignal.setDst(activeCall); packetSignal.setSignalType(SignalType.END_CALL); send(packetSignal); + end(); + } + + const end = () => { + peerConnectionRef.current?.close(); peerConnectionRef.current = null; roomIdRef.current = ""; setActiveCall(""); @@ -386,6 +432,7 @@ export function CallProvider(props : CallProviderProps) { return ( {props.children} + ) diff --git a/app/servers.ts b/app/servers.ts index be66ffa..ce396d3 100644 --- a/app/servers.ts +++ b/app/servers.ts @@ -1,7 +1,7 @@ export const SERVERS = [ //'wss://cdn.rosetta-im.com', - //'ws://10.211.55.2:3000', - 'ws://192.168.6.82:3000', + 'ws://10.211.55.2:3000', + //'ws://192.168.6.82:3000', //'wss://wss.rosetta.im' ];