Emit ICEConnectionState to user API again

This commit is contained in:
Sean DuBois
2018-08-11 00:10:58 -07:00
parent 5a98587a88
commit 02e72796d4
3 changed files with 44 additions and 22 deletions

View File

@@ -63,7 +63,7 @@ func NewManager(bufferTransportGenerator BufferTransportGenerator, dataChannelEv
m.sctpAssociation = sctp.NewAssocation(m.dataChannelOutboundHandler, m.dataChannelInboundHandler)
m.IceAgent = ice.NewAgent(m.iceOutboundHandler)
m.IceAgent = ice.NewAgent(m.iceOutboundHandler, m.iceNotifier)
for _, i := range localInterfaces() {
p, portErr := newPort(i+":0", m)
if portErr != nil {

View File

@@ -20,6 +20,7 @@ type Agent struct {
sync.RWMutex
outboundCallback OutboundCallback
iceNotifier func(ConnectionState)
tieBreaker uint64
connectionState ConnectionState
@@ -50,12 +51,14 @@ const (
)
// NewAgent creates a new Agent
func NewAgent(outboundCallback OutboundCallback) *Agent {
func NewAgent(outboundCallback OutboundCallback, iceNotifier func(ConnectionState)) *Agent {
return &Agent{
tieBreaker: rand.Uint64(),
outboundCallback: outboundCallback,
gatheringState: GatheringStateComplete, // TODO trickle-ice
connectionState: ConnectionStateNew,
iceNotifier: iceNotifier,
tieBreaker: rand.Uint64(),
gatheringState: GatheringStateComplete, // TODO trickle-ice
connectionState: ConnectionStateNew,
LocalUfrag: util.RandSeq(16),
LocalPwd: util.RandSeq(32),
@@ -79,9 +82,7 @@ func (a *Agent) Start(isControlling bool, remoteUfrag, remotePwd string) error {
a.remoteUfrag = remoteUfrag
a.remotePwd = remotePwd
if isControlling {
go a.agentControllingTaskLoop()
}
go a.agentTaskLoop()
return nil
}
@@ -110,28 +111,51 @@ func (a *Agent) pingCandidate(local, remote Candidate) {
})
}
func (a *Agent) agentControllingTaskLoop() {
func (a *Agent) updateConnectionState(newState ConnectionState) {
a.connectionState = newState
a.iceNotifier(a.connectionState)
}
func (a *Agent) setSelectedPair(local, remote Candidate) {
a.selectedPair.remote = remote
a.selectedPair.local = local
a.updateConnectionState(ConnectionStateConnected)
}
func (a *Agent) agentTaskLoop() {
// TODO this should be dynamic, and grow when the connection is stable
t := time.NewTicker(agentTickerBaseInterval)
a.connectionState = ConnectionStateChecking
a.updateConnectionState(ConnectionStateChecking)
assertSelectedPairValid := func() bool {
if a.selectedPair.remote == nil || a.selectedPair.local == nil {
return false
} else if time.Since(a.selectedPair.remote.GetBase().LastSeen) > stunTimeout {
a.selectedPair.remote = nil
a.selectedPair.local = nil
a.updateConnectionState(ConnectionStateDisconnected)
return false
}
return true
}
for {
select {
case <-t.C:
a.Lock()
if a.selectedPair.remote == nil || a.selectedPair.local == nil {
if a.isControlling {
if assertSelectedPairValid() {
continue
}
for _, localCandidate := range a.LocalCandidates {
for _, remoteCandidate := range a.remoteCandidates {
a.pingCandidate(localCandidate, remoteCandidate)
}
}
} else {
if time.Since(a.selectedPair.remote.GetBase().LastSeen) > stunTimeout {
a.selectedPair.remote = nil
a.selectedPair.local = nil
} else {
a.pingCandidate(a.selectedPair.local, a.selectedPair.remote)
}
assertSelectedPairValid()
}
a.Unlock()
case <-a.taskLoopChan:
@@ -205,8 +229,7 @@ func (a *Agent) handleInboundControlled(m *stun.Message, local *stun.TransportAd
}
if _, useCandidateFound := m.GetOneAttribute(stun.AttrUseCandidate); useCandidateFound {
a.selectedPair.remote = remoteCandidate
a.selectedPair.local = localCandidate
a.setSelectedPair(localCandidate, remoteCandidate)
}
a.sendBindingSuccess(m, local, remote)
}
@@ -223,8 +246,7 @@ func (a *Agent) handleInboundControlling(m *stun.Message, local *stun.TransportA
if m.Class == stun.ClassSuccessResponse && m.Method == stun.MethodBinding {
//Binding success!
if a.selectedPair.remote == nil && a.selectedPair.local == nil {
a.selectedPair.remote = remoteCandidate
a.selectedPair.local = localCandidate
a.setSelectedPair(localCandidate, remoteCandidate)
}
} else {
a.sendBindingSuccess(m, local, remote)

View File

@@ -181,7 +181,7 @@ func (r *RTCPeerConnection) iceStateChange(newState ice.ConnectionState) {
r.Lock()
defer r.Unlock()
if r.OnICEConnectionStateChange != nil {
if r.OnICEConnectionStateChange != nil && r.IceConnectionState != newState {
r.OnICEConnectionStateChange(newState)
}
r.IceConnectionState = newState