Skip to content

Commit

Permalink
Fix dc init race
Browse files Browse the repository at this point in the history
  • Loading branch information
streamer45 committed Oct 2, 2024
1 parent b9fc459 commit a22df51
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ type Client struct {

// WebRTC
pc *webrtc.PeerConnection
dc *webrtc.DataChannel
dc atomic.Pointer[webrtc.DataChannel]
iceCh chan webrtc.ICECandidateInit
receivers map[string][]*webrtc.RTPReceiver
voiceSender *webrtc.RTPSender
Expand Down
22 changes: 12 additions & 10 deletions client/rtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (c *Client) handleOffer(sdp string) error {
return fmt.Errorf("failed to set local description: %w", err)
}

if c.cfg.EnableDCSignaling && c.dc.ReadyState() == webrtc.DataChannelStateOpen {
if dataCh := c.dc.Load(); c.cfg.EnableDCSignaling && dataCh != nil && dataCh.ReadyState() == webrtc.DataChannelStateOpen {
c.log.Debug("sending answer through dc")
data, err := json.Marshal(answer)
if err != nil {
Expand All @@ -154,7 +154,7 @@ func (c *Client) handleOffer(sdp string) error {
return fmt.Errorf("failed to encode dc message: %w", err)
}

return c.dc.Send(msg)
return dataCh.Send(msg)
}

if c.cfg.EnableDCSignaling {
Expand Down Expand Up @@ -206,12 +206,6 @@ func (c *Client) initRTCSession() error {
c.pc = pc
c.mut.Unlock()

dataCh, err := pc.CreateDataChannel("calls-dc", nil)
if err != nil {
return fmt.Errorf("failed to create data channel: %w", err)
}
c.dc = dataCh

pc.OnICECandidate(func(candidate *webrtc.ICECandidate) {
if candidate == nil {
c.log.Debug("local ICE gathering completed")
Expand Down Expand Up @@ -332,7 +326,7 @@ func (c *Client) initRTCSession() error {
return
}

if c.cfg.EnableDCSignaling && c.dc.ReadyState() == webrtc.DataChannelStateOpen {
if dataCh := c.dc.Load(); c.cfg.EnableDCSignaling && dataCh != nil && dataCh.ReadyState() == webrtc.DataChannelStateOpen {
c.log.Debug("sending offer through dc")
data, err := json.Marshal(offer)
if err != nil {
Expand All @@ -346,7 +340,7 @@ func (c *Client) initRTCSession() error {
return
}

if err := c.dc.Send(msg); err != nil {
if err := dataCh.Send(msg); err != nil {
c.log.Error("failed to send on dc", slog.String("err", err.Error()))
}
} else {
Expand All @@ -372,6 +366,14 @@ func (c *Client) initRTCSession() error {
}
})

// DC creation must happen after OnNegotiationNeeded has been registered
// to avoid races between dc initialization and initial offer.
dataCh, err := pc.CreateDataChannel("calls-dc", nil)
if err != nil {
return fmt.Errorf("failed to create data channel: %w", err)
}
c.dc.Store(dataCh)

dataCh.OnMessage(func(msg webrtc.DataChannelMessage) {
mt, payload, err := dc.DecodeMessage(msg.Data)
if err != nil {
Expand Down

0 comments on commit a22df51

Please sign in to comment.