public async Task ConnectAsync_TestTransportClientThatEmulatesRtspServer_ConnectionEstablished() { var transportClient = new RtspTransportClientEmulator(); var rtspClient = new RtspClientInternal(_fakeConnectionParameters, () => transportClient); await rtspClient.ConnectAsync(CancellationToken.None); }
public async Task ReceiveAsync_InterleavedModeAndOneRtcpByePacketInStream_SuccessfullyFinished() { var transportClient = new RtspTransportClientEmulator(); var rtspClient = new RtspClientInternal(_fakeConnectionParameters, () => transportClient); await rtspClient.ConnectAsync(CancellationToken.None); await rtspClient.ReceiveAsync(CancellationToken.None); }
public async Task ConnectAsync_CancellationRequested_ThrowsException() { var transportClient = new RtspTransportClientEmulator(); var cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.Cancel(); var rtspClient = new RtspClientInternal(_fakeConnectionParameters, () => transportClient); await rtspClient.ConnectAsync(cancellationTokenSource.Token); }
public async Task ReceiveAsync_CancellationRequested_ImmediateReturn() { var transportClient = new RtspTransportClientEmulator(); var rtspClient = new RtspClientInternal(_fakeConnectionParameters, () => transportClient); var cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.Cancel(); await rtspClient.ConnectAsync(CancellationToken.None); await rtspClient.ReceiveAsync(cancellationTokenSource.Token); }
/// <summary> /// Clean up unmanaged resources /// </summary> public void Dispose() { if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) { return; } RtspClientInternal rtspClientInternal = Volatile.Read(ref _rtspClientInternal); rtspClientInternal?.Dispose(); GC.SuppressFinalize(this); }
/// <summary> /// Connect to endpoint and start RTSP session /// </summary> /// <exception cref="OperationCanceledException"></exception> /// <exception cref="InvalidCredentialException"></exception> /// <exception cref="RtspClientException"></exception> public async Task ConnectAsync(CancellationToken token) { await Task.Run(async() => { _rtspClientInternal = CreateRtspClientInternal(ConnectionParameters, _transportClientProvider); try { Task connectionTask = _rtspClientInternal.ConnectAsync(token); if (connectionTask.IsCompleted) { await connectionTask; return; } var delayTaskCancelTokenSource = new CancellationTokenSource(); using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(delayTaskCancelTokenSource.Token, token)) { CancellationToken delayTaskToken = linkedTokenSource.Token; Task delayTask = Task.Delay(ConnectionParameters.ConnectTimeout, delayTaskToken); if (connectionTask != await Task.WhenAny(connectionTask, delayTask)) { connectionTask.IgnoreExceptions(); if (delayTask.IsCanceled) { throw new OperationCanceledException(); } throw new TimeoutException(); } delayTaskCancelTokenSource.Cancel(); await connectionTask; } } catch (Exception e) { _rtspClientInternal.Dispose(); Volatile.Write(ref _rtspClientInternal, null); if (e is TimeoutException) { throw new RtspClientException("Connection timeout", e); } if (e is OperationCanceledException) { throw; } if (e is RtspBadResponseCodeException rtspBadResponseCodeException && rtspBadResponseCodeException.Code == RtspStatusCode.Unauthorized || e is HttpBadResponseCodeException httpBadResponseCodeException && httpBadResponseCodeException.Code == HttpStatusCode.Unauthorized) { throw new InvalidCredentialException("Invalid login and/or password"); } if (!(e is RtspClientException)) { throw new RtspClientException("Connection error", e); } throw; } }, token).ConfigureAwait(false); }