public IEnumerable <IOnvifUdpClient> CreateClientForeachInterface() { var clients = new List <IOnvifUdpClient> (); NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in nics) { if (!IsValidAdapter(adapter)) { continue; } IPInterfaceProperties adapterProperties = adapter.GetIPProperties(); foreach (var ua in adapterProperties.UnicastAddresses) { if (ua.Address.AddressFamily == AddressFamily.InterNetwork) { IPEndPoint myLocalEndPoint = new IPEndPoint(ua.Address, 0); // port does not matter try { IOnvifUdpClient client = CreateClient(myLocalEndPoint); clients.Add(client); } catch (SocketException) { // Discard clients that produces a SocketException when created } } } } return(clients); }
async Task <IEnumerable <DiscoveryDevice> > Discover(int timeout, IOnvifUdpClient client, CancellationToken cancellationToken = default) { Guid messageId = Guid.NewGuid(); var responses = new List <UdpReceiveResult> (); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout)); try { await SendProbe(client, messageId); while (true) { if (cts.IsCancellationRequested || cancellationToken.IsCancellationRequested) { break; } var response = await client.ReceiveAsync().WithCancellation(cancellationToken).WithCancellation(cts.Token); if (!IsAlreadyDiscovered(response, responses)) { responses.Add(response); } } } catch (OperationCanceledException) { // Either the user canceled the action or the timeout has fired } finally { client.Close(); } if (cancellationToken.IsCancellationRequested) { return(new List <DiscoveryDevice> ()); } return(ProcessResponses(responses, messageId)); }
async Task Discover(int timeout, IOnvifUdpClient client, Action <DiscoveryDevice> onDeviceDiscovered, CancellationToken cancellationToken = default) { Guid messageId = Guid.NewGuid(); var responses = new List <UdpReceiveResult> (); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout)); try { await SendProbe(client, messageId); while (true) { if (cts.IsCancellationRequested || cancellationToken.IsCancellationRequested) { break; } try { var response = await client.ReceiveAsync() .WithCancellation(cancellationToken) .WithCancellation(cts.Token); if (IsAlreadyDiscovered(response, responses)) { continue; } responses.Add(response); var discoveredDevice = ProcessResponse(response, messageId); if (discoveredDevice != null) { #pragma warning disable 4014 // Just trigger the callback and forget about it. This is expected to avoid locking the loop Task.Run(() => onDeviceDiscovered(discoveredDevice)); #pragma warning restore 4014 } } catch (OperationCanceledException) { // Either the user canceled the action or the timeout has fired } catch (Exception) { // we catch all exceptions ! // Something might be bad in the response of a camera when call ReceiveAsync (BeginReceive in socket) fail } } } finally { client.Close(); } }
async Task SendProbe(IOnvifUdpClient client, Guid messageId) { var multicastEndpoint = new IPEndPoint(IPAddress.Parse(Constants.WS_MULTICAST_ADDRESS), Constants.WS_MULTICAST_PORT); await client.SendProbeAsync(messageId, multicastEndpoint); }