public async void CheckSuccessfulConnectionForRelayCandidatesUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); using (MockTurnServer mockTurnServer = new MockTurnServer()) { var iceServers = new List <RTCIceServer> { new RTCIceServer { urls = $"turn:{mockTurnServer.ListeningEndPoint}", } }; var rtpIceChannelRelay = new RtpIceChannel(null, RTCIceComponent.rtp, iceServers, RTCIceTransportPolicy.relay); rtpIceChannelRelay.IsController = true; logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelRelay.RTPLocalEndPoint}."); var rtpIceChannelHost = new RtpIceChannel(); logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelHost.RTPLocalEndPoint}."); rtpIceChannelRelay.StartGathering(); rtpIceChannelHost.StartGathering(); // Need to give some time for the relay channel to connect to the mock TURN server. await Task.Delay(200); Assert.Single(rtpIceChannelRelay.Candidates); // Should only have the single local relay candidate. Assert.NotEmpty(rtpIceChannelHost.Candidates); Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelRelay.IceGatheringState); Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelRelay.IceConnectionState); Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelHost.IceGatheringState); Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelHost.IceConnectionState); // Exchange ICE user and passwords. rtpIceChannelRelay.SetRemoteCredentials(rtpIceChannelHost.LocalIceUser, rtpIceChannelHost.LocalIcePassword); rtpIceChannelHost.SetRemoteCredentials(rtpIceChannelRelay.LocalIceUser, rtpIceChannelRelay.LocalIcePassword); Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelRelay.IceConnectionState); Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelHost.IceConnectionState); // Exchange ICE candidates. rtpIceChannelRelay.Candidates.ForEach(x => rtpIceChannelHost.AddRemoteCandidate(x)); rtpIceChannelHost.Candidates.ForEach(x => rtpIceChannelRelay.AddRemoteCandidate(x)); await Task.Delay(1000); Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelRelay.IceConnectionState); Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelHost.IceConnectionState); Assert.NotNull(rtpIceChannelRelay.NominatedEntry); Assert.NotNull(rtpIceChannelHost.NominatedEntry); } }
public async void CheckIPAddressOnlyStunServerUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); using (MockTurnServer mockStunServer = new MockTurnServer()) { // Give the TURN server socket receive tasks time to fire up. await Task.Delay(1000); var iceServers = new List <RTCIceServer> { new RTCIceServer { urls = $"stun:{mockStunServer.ListeningEndPoint}", } }; var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, iceServers); logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannel.RTPLocalEndPoint}."); ManualResetEventSlim gatheringCompleted = new ManualResetEventSlim(); rtpIceChannel.OnIceGatheringStateChange += (state) => { if (state == RTCIceGatheringState.complete) { gatheringCompleted.Set(); } }; rtpIceChannel.StartGathering(); Assert.NotEmpty(rtpIceChannel.Candidates); // Because there is an ICE server gathering should still be in progress. Assert.Equal(RTCIceGatheringState.gathering, rtpIceChannel.IceGatheringState); Assert.Equal(RTCIceConnectionState.@new, rtpIceChannel.IceConnectionState); Assert.True(gatheringCompleted.Wait(3000)); // The STUN server check should now have completed and a server reflexive candidate // been acquired Assert.Equal(RTCIceGatheringState.complete, rtpIceChannel.IceGatheringState); // The connection state stays in "new" because no remote ICE user and password has been set. Assert.Equal(RTCIceConnectionState.@new, rtpIceChannel.IceConnectionState); Assert.Contains(rtpIceChannel.Candidates, x => x.type == RTCIceCandidateType.srflx); } }