@@ -72,7 +72,8 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
72
72
dcDisconnectChannel : make (chan struct {}),
73
73
dcFailedChannel : make (chan struct {}),
74
74
localCandidateChannel : make (chan webrtc.ICECandidateInit ),
75
- pendingCandidates : make ([]webrtc.ICECandidateInit , 0 ),
75
+ pendingLocalCandidates : make ([]webrtc.ICECandidateInit , 0 ),
76
+ pendingRemoteCandidates : make ([]webrtc.ICECandidateInit , 0 ),
76
77
localSessionDescriptionChannel : make (chan webrtc.SessionDescription ),
77
78
remoteSessionDescriptionChannel : make (chan webrtc.SessionDescription ),
78
79
}
@@ -120,7 +121,8 @@ type Conn struct {
120
121
localSessionDescriptionChannel chan webrtc.SessionDescription
121
122
remoteSessionDescriptionChannel chan webrtc.SessionDescription
122
123
123
- pendingCandidates []webrtc.ICECandidateInit
124
+ pendingLocalCandidates []webrtc.ICECandidateInit
125
+ pendingRemoteCandidates []webrtc.ICECandidateInit
124
126
pendingCandidatesMutex sync.Mutex
125
127
pendingCandidatesFlushed bool
126
128
@@ -147,7 +149,7 @@ func (c *Conn) init() error {
147
149
148
150
if ! c .pendingCandidatesFlushed {
149
151
c .opts .Logger .Debug (context .Background (), "adding local candidate to buffer" )
150
- c .pendingCandidates = append (c .pendingCandidates , iceCandidate .ToJSON ())
152
+ c .pendingLocalCandidates = append (c .pendingLocalCandidates , iceCandidate .ToJSON ())
151
153
return
152
154
}
153
155
c .opts .Logger .Debug (context .Background (), "adding local candidate" )
@@ -291,7 +293,10 @@ func (c *Conn) negotiate() {
291
293
if c .offerrer {
292
294
// ICE candidates reset when an offer/answer is set for the first
293
295
// time. If candidates flush before this point, a connection could fail.
294
- c .flushPendingCandidates ()
296
+ err = c .flushPendingCandidates ()
297
+ if err != nil {
298
+ _ = c .CloseWithError (xerrors .Errorf ("flush pending candidates: %w" , err ))
299
+ }
295
300
}
296
301
297
302
if ! c .offerrer {
@@ -315,26 +320,39 @@ func (c *Conn) negotiate() {
315
320
}
316
321
317
322
// Wait until the local description is set to flush candidates.
318
- c .flushPendingCandidates ()
323
+ err = c .flushPendingCandidates ()
324
+ if err != nil {
325
+ _ = c .CloseWithError (xerrors .Errorf ("flush pending candidates: %w" , err ))
326
+ }
319
327
}
320
328
}
321
329
322
330
// flushPendingCandidates writes all local candidates to the candidate send channel.
323
331
// The localCandidateChannel is expected to be serviced, otherwise this could block.
324
- func (c * Conn ) flushPendingCandidates () {
332
+ func (c * Conn ) flushPendingCandidates () error {
325
333
c .pendingCandidatesMutex .Lock ()
326
334
defer c .pendingCandidatesMutex .Unlock ()
327
- for _ , pendingCandidate := range c .pendingCandidates {
335
+ for _ , pendingCandidate := range c .pendingLocalCandidates {
328
336
c .opts .Logger .Debug (context .Background (), "flushing local candidate" )
329
337
select {
330
338
case <- c .closed :
331
- return
339
+ return nil
332
340
case c .localCandidateChannel <- pendingCandidate :
333
341
}
334
342
}
335
- c .pendingCandidates = make ([]webrtc.ICECandidateInit , 0 )
343
+
344
+ for _ , pendingCandidate := range c .pendingRemoteCandidates {
345
+ c .opts .Logger .Debug (context .Background (), "flushing remote candidate" )
346
+ err := c .rtc .AddICECandidate (pendingCandidate )
347
+ if err != nil {
348
+ return err
349
+ }
350
+ }
351
+
352
+ c .pendingLocalCandidates = make ([]webrtc.ICECandidateInit , 0 )
336
353
c .pendingCandidatesFlushed = true
337
354
c .opts .Logger .Debug (context .Background (), "flushed candidates" )
355
+ return nil
338
356
}
339
357
340
358
// LocalCandidate returns a channel that emits when a local candidate
@@ -345,6 +363,13 @@ func (c *Conn) LocalCandidate() <-chan webrtc.ICECandidateInit {
345
363
346
364
// AddRemoteCandidate adds a remote candidate to the RTC connection.
347
365
func (c * Conn ) AddRemoteCandidate (i webrtc.ICECandidateInit ) error {
366
+ c .pendingCandidatesMutex .Lock ()
367
+ defer c .pendingCandidatesMutex .Unlock ()
368
+ if ! c .pendingCandidatesFlushed {
369
+ c .opts .Logger .Debug (context .Background (), "adding remote candidate to buffer" )
370
+ c .pendingRemoteCandidates = append (c .pendingRemoteCandidates , i )
371
+ return nil
372
+ }
348
373
c .opts .Logger .Debug (context .Background (), "adding remote candidate" )
349
374
return c .rtc .AddICECandidate (i )
350
375
}
0 commit comments