Исправление Race при renegotiation

This commit is contained in:
set
2026-03-17 19:17:02 +02:00
parent 96df1e52f9
commit 6dadec6b64
6 changed files with 109 additions and 78 deletions

View File

@@ -1,6 +1,7 @@
package sfu
import (
"g365sfu/logger"
connection "g365sfu/socket/struct"
"sync"
@@ -76,43 +77,9 @@ func JoinWithOffer(roomID string, peerID string, offer webrtc.SessionDescription
return nil, err
}
peerConnection.OnICECandidate(func(c *webrtc.ICECandidate) {
if c == nil {
return
}
if OnLocalICECandidate != nil {
OnLocalICECandidate(roomID, peerID, c.ToJSON())
}
})
BindPeerLifecycle(roomID, peerID, peerConnection)
SetupForwardingForPeer(roomID, peerID, peerConnection)
room.mu.RLock()
existingTracks := make([]RoomTrack, len(room.Tracks))
copy(existingTracks, room.Tracks)
room.mu.RUnlock()
for _, t := range existingTracks {
if t.OwnerPeer == peerID {
continue
}
sender, err := peerConnection.AddTrack(t.Local)
if err != nil {
continue
}
go func() {
buf := make([]byte, 1500)
for {
if _, _, e := sender.Read(buf); e != nil {
return
}
}
}()
}
if err = peerConnection.SetRemoteDescription(offer); err != nil {
_ = peerConnection.Close()
return nil, err
@@ -131,13 +98,57 @@ func JoinWithOffer(roomID string, peerID string, offer webrtc.SessionDescription
}
<-gatherDone
peerConnection.OnICECandidate(func(c *webrtc.ICECandidate) {
if c == nil {
return
}
if OnLocalICECandidate != nil {
OnLocalICECandidate(roomID, peerID, c.ToJSON())
}
})
// Добавляем peer в комнату и сразу снимаем snapshot существующих треков
// в одном локе — чтобы не было race с OnTrack
room.mu.Lock()
room.Peers = append(room.Peers, Peer{
PeerID: peerID,
PeerConnection: peerConnection,
})
existingTracks := make([]RoomTrack, len(room.Tracks))
copy(existingTracks, room.Tracks)
room.mu.Unlock()
// Подписываем нового peer на уже существующие треки ПОСЛЕ добавления в комнату
for _, t := range existingTracks {
if t.OwnerPeer == peerID {
continue
}
sender, err := peerConnection.AddTrack(t.Local)
if err != nil {
continue
}
senderCopy := sender
go func() {
buf := make([]byte, 1500)
for {
if _, _, e := senderCopy.Read(buf); e != nil {
return
}
}
}()
}
// Если были добавлены треки — нужна renegotiation
if len(existingTracks) > 0 {
go func() {
if err := renegotiatePeer(roomID, peerID, peerConnection); err != nil {
logger.LogWarnMessage("JoinWithOffer: renegotiatePeer error: " + err.Error())
}
}()
}
return peerConnection.LocalDescription(), nil
}