@@ -63,7 +63,6 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
63
63
conn := & Conn {
64
64
pingChannelID : 1 ,
65
65
pingEchoChannelID : 2 ,
66
- opts : opts ,
67
66
rtc : rtc ,
68
67
offerer : client ,
69
68
closed : make (chan struct {}),
@@ -75,7 +74,9 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
75
74
localCandidateChannel : make (chan webrtc.ICECandidateInit ),
76
75
localSessionDescriptionChannel : make (chan webrtc.SessionDescription , 1 ),
77
76
remoteSessionDescriptionChannel : make (chan webrtc.SessionDescription , 1 ),
77
+ settingEngine : opts .SettingEngine ,
78
78
}
79
+ conn .loggerValue .Store (opts .Logger )
79
80
if client {
80
81
// If we're the client, we want to flip the echo and
81
82
// ping channel IDs so pings don't accidentally hit each other.
@@ -100,8 +101,7 @@ type ConnOptions struct {
100
101
// This struct wraps webrtc.PeerConnection to add bidirectional pings,
101
102
// concurrent-safe webrtc.DataChannel, and standardized errors for connection state.
102
103
type Conn struct {
103
- rtc * webrtc.PeerConnection
104
- opts * ConnOptions
104
+ rtc * webrtc.PeerConnection
105
105
// Determines whether this connection will send the offer or the answer.
106
106
offerer bool
107
107
@@ -127,6 +127,9 @@ type Conn struct {
127
127
negotiateMutex sync.Mutex
128
128
hasNegotiated bool
129
129
130
+ loggerValue atomic.Value
131
+ settingEngine webrtc.SettingEngine
132
+
130
133
pingChannelID uint16
131
134
pingEchoChannelID uint16
132
135
@@ -139,6 +142,14 @@ type Conn struct {
139
142
pingError error
140
143
}
141
144
145
+ func (c * Conn ) logger () slog.Logger {
146
+ log , valid := c .loggerValue .Load ().(slog.Logger )
147
+ if ! valid {
148
+ return slog.Logger {}
149
+ }
150
+ return log
151
+ }
152
+
142
153
func (c * Conn ) init () error {
143
154
// The negotiation needed callback can take a little bit to execute!
144
155
c .negotiateMutex .Lock ()
@@ -152,7 +163,7 @@ func (c *Conn) init() error {
152
163
// Don't log more state changes if we've already closed.
153
164
return
154
165
default :
155
- c .opts . Logger .Debug (context .Background (), "ice connection state updated" ,
166
+ c .logger () .Debug (context .Background (), "ice connection state updated" ,
156
167
slog .F ("state" , iceConnectionState ))
157
168
158
169
if iceConnectionState == webrtc .ICEConnectionStateClosed {
@@ -171,7 +182,7 @@ func (c *Conn) init() error {
171
182
// Don't log more state changes if we've already closed.
172
183
return
173
184
default :
174
- c .opts . Logger .Debug (context .Background (), "ice gathering state updated" ,
185
+ c .logger () .Debug (context .Background (), "ice gathering state updated" ,
175
186
slog .F ("state" , iceGatherState ))
176
187
177
188
if iceGatherState == webrtc .ICEGathererStateClosed {
@@ -189,7 +200,7 @@ func (c *Conn) init() error {
189
200
if c .isClosed () {
190
201
return
191
202
}
192
- c .opts . Logger .Debug (context .Background (), "rtc connection updated" ,
203
+ c .logger () .Debug (context .Background (), "rtc connection updated" ,
193
204
slog .F ("state" , peerConnectionState ))
194
205
}()
195
206
@@ -225,38 +236,25 @@ func (c *Conn) init() error {
225
236
// These functions need to check if the conn is closed, because they can be
226
237
// called after being closed.
227
238
c .rtc .OnSignalingStateChange (func (signalState webrtc.SignalingState ) {
228
- if c .isClosed () {
229
- return
230
- }
231
- c .opts .Logger .Debug (context .Background (), "signaling state updated" ,
239
+ c .logger ().Debug (context .Background (), "signaling state updated" ,
232
240
slog .F ("state" , signalState ))
233
241
})
234
242
c .rtc .SCTP ().Transport ().OnStateChange (func (dtlsTransportState webrtc.DTLSTransportState ) {
235
- if c .isClosed () {
236
- return
237
- }
238
- c .opts .Logger .Debug (context .Background (), "dtls transport state updated" ,
243
+ c .logger ().Debug (context .Background (), "dtls transport state updated" ,
239
244
slog .F ("state" , dtlsTransportState ))
240
245
})
241
246
c .rtc .SCTP ().Transport ().ICETransport ().OnSelectedCandidatePairChange (func (candidatePair * webrtc.ICECandidatePair ) {
242
- if c .isClosed () {
243
- return
244
- }
245
- c .opts .Logger .Debug (context .Background (), "selected candidate pair changed" ,
247
+ c .logger ().Debug (context .Background (), "selected candidate pair changed" ,
246
248
slog .F ("local" , candidatePair .Local ), slog .F ("remote" , candidatePair .Remote ))
247
249
})
248
250
c .rtc .OnICECandidate (func (iceCandidate * webrtc.ICECandidate ) {
249
- if c .isClosed () {
250
- return
251
- }
252
-
253
251
if iceCandidate == nil {
254
252
return
255
253
}
256
254
// Run this in a goroutine so we don't block pion/webrtc
257
255
// from continuing.
258
256
go func () {
259
- c .opts . Logger .Debug (context .Background (), "sending local candidate" , slog .F ("candidate" , iceCandidate .ToJSON ().Candidate ))
257
+ c .logger () .Debug (context .Background (), "sending local candidate" , slog .F ("candidate" , iceCandidate .ToJSON ().Candidate ))
260
258
select {
261
259
case <- c .closed :
262
260
break
@@ -287,7 +285,7 @@ func (c *Conn) init() error {
287
285
// negotiate is triggered when a connection is ready to be established.
288
286
// See trickle ICE for the expected exchange: https://webrtchacks.com/trickle-ice/
289
287
func (c * Conn ) negotiate () {
290
- c .opts . Logger .Debug (context .Background (), "negotiating" )
288
+ c .logger () .Debug (context .Background (), "negotiating" )
291
289
// ICE candidates cannot be added until SessionDescriptions have been
292
290
// exchanged between peers.
293
291
if c .hasNegotiated {
@@ -311,23 +309,23 @@ func (c *Conn) negotiate() {
311
309
_ = c .CloseWithError (xerrors .Errorf ("set local description: %w" , err ))
312
310
return
313
311
}
314
- c .opts . Logger .Debug (context .Background (), "sending offer" , slog .F ("offer" , offer ))
312
+ c .logger () .Debug (context .Background (), "sending offer" , slog .F ("offer" , offer ))
315
313
select {
316
314
case <- c .closed :
317
315
return
318
316
case c .localSessionDescriptionChannel <- offer :
319
317
}
320
- c .opts . Logger .Debug (context .Background (), "sent offer" )
318
+ c .logger () .Debug (context .Background (), "sent offer" )
321
319
}
322
320
323
321
var sessionDescription webrtc.SessionDescription
324
- c .opts . Logger .Debug (context .Background (), "awaiting remote description..." )
322
+ c .logger () .Debug (context .Background (), "awaiting remote description..." )
325
323
select {
326
324
case <- c .closed :
327
325
return
328
326
case sessionDescription = <- c .remoteSessionDescriptionChannel :
329
327
}
330
- c .opts . Logger .Debug (context .Background (), "setting remote description" )
328
+ c .logger () .Debug (context .Background (), "setting remote description" )
331
329
332
330
err := c .rtc .SetRemoteDescription (sessionDescription )
333
331
if err != nil {
@@ -350,13 +348,13 @@ func (c *Conn) negotiate() {
350
348
_ = c .CloseWithError (xerrors .Errorf ("set local description: %w" , err ))
351
349
return
352
350
}
353
- c .opts . Logger .Debug (context .Background (), "sending answer" , slog .F ("answer" , answer ))
351
+ c .logger () .Debug (context .Background (), "sending answer" , slog .F ("answer" , answer ))
354
352
select {
355
353
case <- c .closed :
356
354
return
357
355
case c .localSessionDescriptionChannel <- answer :
358
356
}
359
- c .opts . Logger .Debug (context .Background (), "sent answer" )
357
+ c .logger () .Debug (context .Background (), "sent answer" )
360
358
}
361
359
}
362
360
@@ -373,7 +371,7 @@ func (c *Conn) AddRemoteCandidate(i webrtc.ICECandidateInit) {
373
371
if c .isClosed () {
374
372
return
375
373
}
376
- c .opts . Logger .Debug (context .Background (), "accepting candidate" , slog .F ("candidate" , i .Candidate ))
374
+ c .logger () .Debug (context .Background (), "accepting candidate" , slog .F ("candidate" , i .Candidate ))
377
375
err := c .rtc .AddICECandidate (i )
378
376
if err != nil {
379
377
if c .rtc .ConnectionState () == webrtc .PeerConnectionStateClosed {
@@ -482,7 +480,7 @@ func (c *Conn) Dial(ctx context.Context, label string, opts *ChannelOptions) (*C
482
480
}
483
481
484
482
func (c * Conn ) dialChannel (ctx context.Context , label string , opts * ChannelOptions ) (* Channel , error ) {
485
- c .opts . Logger .Debug (ctx , "creating data channel" , slog .F ("label" , label ), slog .F ("opts" , opts ))
483
+ c .logger () .Debug (ctx , "creating data channel" , slog .F ("label" , label ), slog .F ("opts" , opts ))
486
484
var id * uint16
487
485
if opts .ID != 0 {
488
486
id = & opts .ID
@@ -531,7 +529,7 @@ func (c *Conn) Ping() (time.Duration, error) {
531
529
if err != nil {
532
530
return 0 , xerrors .Errorf ("send ping: %w" , err )
533
531
}
534
- c .opts . Logger .Debug (context .Background (), "wrote ping" ,
532
+ c .logger () .Debug (context .Background (), "wrote ping" ,
535
533
slog .F ("connection_state" , c .rtc .ConnectionState ()))
536
534
537
535
pingDataReceived := make ([]byte , pingDataLength )
@@ -568,12 +566,11 @@ func (c *Conn) isClosed() bool {
568
566
func (c * Conn ) CloseWithError (err error ) error {
569
567
c .closeMutex .Lock ()
570
568
defer c .closeMutex .Unlock ()
571
-
572
569
if c .isClosed () {
573
570
return c .closeError
574
571
}
575
572
576
- c .opts . Logger .Debug (context .Background (), "closing conn with error" , slog .Error (err ))
573
+ c .logger () .Debug (context .Background (), "closing conn with error" , slog .Error (err ))
577
574
if err == nil {
578
575
c .closeError = ErrClosed
579
576
} else {
@@ -591,19 +588,21 @@ func (c *Conn) CloseWithError(err error) error {
591
588
// Waiting for pion/webrtc to report closed state on both of these
592
589
// ensures no goroutine leaks.
593
590
if c .rtc .ConnectionState () != webrtc .PeerConnectionStateNew {
594
- c .opts . Logger .Debug (context .Background (), "waiting for rtc connection close..." )
591
+ c .logger () .Debug (context .Background (), "waiting for rtc connection close..." )
595
592
<- c .closedRTC
596
593
}
597
594
if c .rtc .ICEConnectionState () != webrtc .ICEConnectionStateNew {
598
- c .opts . Logger .Debug (context .Background (), "waiting for ice connection close..." )
595
+ c .logger () .Debug (context .Background (), "waiting for ice connection close..." )
599
596
<- c .closedICE
600
597
}
601
598
602
599
// Waits for all DataChannels to exit before officially labeling as closed.
603
600
// All logging, goroutines, and async functionality is cleaned up after this.
604
601
c .dcClosedWaitGroup .Wait ()
605
602
606
- c .opts .Logger .Debug (context .Background (), "closed" )
603
+ c .logger ().Debug (context .Background (), "closed" )
604
+ // Disable logging!
605
+ c .loggerValue .Store (slog.Logger {})
607
606
close (c .closed )
608
607
return err
609
608
}
0 commit comments