public void Setup()
        {
            this.deviceClientMock        = new Mock <IDeviceClient>();
            this.clientWebSocket         = new Mock <IClientWebSocket>();
            this.tcpClient               = new Mock <ITcpClient>();
            this.networkStream           = new Mock <Stream>();
            this.realClientWebSocket     = new ClientWebSocket();
            this.cancellationTokenSource = new CancellationTokenSource();

            this.deviceStreamRequest = new DeviceStreamRequest("001", "teststream01", uri, "dsdfsdrer32");

            this.deviceClientMock.Setup(dc => dc.WaitForDeviceStreamRequestAsync(this.cancellationTokenSource.Token))
            .ReturnsAsync(() => { return(this.deviceStreamRequest); });

            this.clientWebSocket.Setup(dc => dc.ConnectAsync(uri, this.cancellationTokenSource.Token))
            .Returns(Task.FromResult(0));
            this.clientWebSocket.Setup(dc => dc.ReceiveAsync(this.buffer, this.cancellationTokenSource.Token))
            .ReturnsAsync(new WebSocketReceiveResult(streamReturnValue, WebSocketMessageType.Binary, true));

            this.clientWebSocket.Setup(dc => dc.Options).Returns(this.realClientWebSocket.Options);
            this.clientWebSocket.Setup(dc => dc.State).Returns(() => { this.toggleStateWebSocket = !this.toggleStateWebSocket; return(this.toggleStateWebSocket ? WebSocketState.Open : WebSocketState.Closed); });

            this.tcpClient.Setup(tc => tc.ConnectAsync(localhost, localPort)).Returns(Task.FromResult(0));
            this.tcpClient.Setup(tc => tc.GetStream()).Returns(this.networkStream.Object);

            this.networkStream.Setup(ns => ns.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), this.cancellationTokenSource.Token)).Returns(Task.FromResult(0));
            this.networkStream.Setup(ns => ns.CanRead).Returns(() => { this.toggleStateNetworkStream = !this.toggleStateNetworkStream; return(this.toggleStateNetworkStream ? true : false); });

            this.networkStream.Setup(ns => ns.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), this.cancellationTokenSource.Token)).ReturnsAsync((byte[] r, int o, int s, CancellationToken cts) =>
            {
                r[0] = 1;
                return(streamReturnValue);
            });
        }
Exemple #2
0
        /// <summary>
        /// Accepts the device stream request, connects to the local proxy target and maintains incoming and outgoing connections
        /// </summary>
        /// <param name="request">The device stream request</param>
        /// <param name="cancellationToken">Token used for cancelling this operation</param>
        /// <returns>An awaitable async task</returns>
        private async Task InitiateProxyConnectionsAsync(DeviceStreamRequest request, CancellationToken cancellationToken)
        {
            try
            {
                logger.LogInformation($"Starting a proxy connection. RequestId: {request.RequestId} Name: {request.Name}");

                await deviceClient.AcceptDeviceStreamRequestAsync(request, cancellationToken).ConfigureAwait(false);

                using var streamClient = await GetStreamingClientAsync(request.Uri, request.AuthorizationToken, cancellationToken).ConfigureAwait(false);

                using (var tcpClient = new TcpClient())
                {
                    await tcpClient.ConnectAsync(settings.RemoteHost, settings.RemotePort).ConfigureAwait(false);

                    using var networkStream = tcpClient.GetStream();

                    await Task.WhenAny(
                        HandleIncomingDataAsync(networkStream, streamClient, cancellationToken),
                        HandleOutgoingDataAsync(networkStream, streamClient, cancellationToken)).ConfigureAwait(false);

                    networkStream.Close();
                }

                await streamClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                logger.LogInformation($"Stopped a proxy connection. RequestId: {request.RequestId} Name: {request.Name}");
            }
        }
        public async Task RunSampleAsync(bool acceptDeviceStreamingRequest, CancellationTokenSource cancellationTokenSource)
        {
            try
            {
                Update("Awaiting connection.");
                DeviceStreamRequest streamRequest = await _deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token).ConfigureAwait(false);

                Update("Got request.");
                if (streamRequest != null)
                {
                    if (acceptDeviceStreamingRequest)
                    {
                        try
                        {
                            await _deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);

                            Update("Accepted request.");
                            using (ClientWebSocket webSocket = await DeviceStreamingCommon.GetStreamingClientAsync(streamRequest.Url, streamRequest.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                            {
                                Update("Got client stream.");
                                using (TcpClient tcpClient = new TcpClient())
                                {
                                    Update("Connecting to stream.");
                                    await tcpClient.ConnectAsync(_host, _port).ConfigureAwait(false);

                                    using (NetworkStream localStream = tcpClient.GetStream())
                                    {
                                        Update("Device starting streaming");
                                        counter = 0;
                                        await Task.WhenAny(
                                            HandleIncomingDataAsync(localStream, webSocket, cancellationTokenSource.Token),
                                            HandleOutgoingDataAsync(localStream, webSocket, cancellationTokenSource.Token)).ConfigureAwait(false);

                                        Update("Closing stream");
                                        localStream.Close();
                                        Update("Closed stream");
                                    }
                                }

                                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSource.Token).ConfigureAwait(false);
                            }
                        }
                        catch (Exception ex)
                        {
                            Update("Device got an inner exception. Exiting connection."); //: {0}", ex);
                        }
                    }
                    else
                    {
                        await _deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMsg("Device got an outer exception", ex);
            }
        }
        public static async Task <ClientWebSocket> ConnectToDevice(this ServiceClient serviceClient, string deviceId, CancellationToken ct, string streamName = "EdgeStream")
        {
            DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(streamName);

            Console.WriteLine($"Connecting to {deviceId}");
            DeviceStreamResponse streamInfo = await serviceClient.CreateStreamAsync(deviceId, deviceStreamRequest, ct).ConfigureAwait(false);

            Console.WriteLine($"Stream response received: Name={deviceStreamRequest.StreamName} IsAccepted={streamInfo.IsAccepted}");

            return(await DeviceStreamWebsocket.MakeWebSocket(streamInfo.Url, streamInfo.AuthorizationToken, ct));
        }
        public async Task RegisterDevice(IConfigurationRoot configuration)
        {
            string deviceConnectionString = configuration.GetValue <string>("DeviceConnectionString");

            Console.WriteLine($"DeviceConnectionString: {deviceConnectionString}");
            DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, TransportType.Amqp_WebSocket_Only);

            while (true)
            {
                try {
                    Console.WriteLine("Waiting for stream request");
                    Console.WriteLine($"Before: {DateTime.Now.ToString()}");
                    DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync();

                    Console.WriteLine("Received stream request");
                    if (streamRequest != null)
                    {
                        await deviceClient.AcceptDeviceStreamRequestAsync(streamRequest);

                        using (ClientWebSocket webSocket = await GetStreamingClientAsync(streamRequest.Url, streamRequest.AuthorizationToken))
                        {
                            using (TcpClient tcpClient = new TcpClient())
                            {
                                string host = configuration.GetValue <string>("ProxyHostName");
                                int    port = configuration.GetValue <int>("ProxyPort");
                                await tcpClient.ConnectAsync(host, port).ConfigureAwait(false);

                                using (NetworkStream localStream = tcpClient.GetStream())
                                {
                                    Console.WriteLine("Starting streaming");

                                    await Task.WhenAny(
                                        HandleIncomingDataAsync(localStream, webSocket),
                                        HandleOutgoingDataAsync(localStream, webSocket));

                                    localStream.Close();
                                }
                            }

                            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None);
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"After: {DateTime.Now.ToString()}");
                    Console.WriteLine($"Exception: {e.ToString()}");
                }
            }
        }
Exemple #6
0
        public async Task RunSampleAsync(bool acceptDeviceStreamingRequest = true)
        {
            byte[] buffer = new byte[1024];

            using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5)))
            {
                DeviceStreamRequest streamRequest = await _deviceClient
                                                    .WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token)
                                                    .ConfigureAwait(false);

                if (streamRequest != null)
                {
                    if (acceptDeviceStreamingRequest)
                    {
                        await _deviceClient
                        .AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token)
                        .ConfigureAwait(false);

                        using (ClientWebSocket webSocket = await DeviceStreamingCommon
                                                           .GetStreamingClientAsync(streamRequest.Url, streamRequest.AuthorizationToken, cancellationTokenSource.Token)
                                                           .ConfigureAwait(false))
                        {
                            WebSocketReceiveResult receiveResult = await webSocket
                                                                   .ReceiveAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), cancellationTokenSource.Token)
                                                                   .ConfigureAwait(false);

                            Console.WriteLine("Received stream data: {0}", Encoding.UTF8.GetString(buffer, 0, receiveResult.Count));

                            await webSocket
                            .SendAsync(new ArraySegment <byte>(buffer, 0, receiveResult.Count), WebSocketMessageType.Binary, true, cancellationTokenSource.Token)
                            .ConfigureAwait(false);

                            Console.WriteLine("Sent stream data: {0}", Encoding.UTF8.GetString(buffer, 0, receiveResult.Count));

                            await webSocket
                            .CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationTokenSource.Token)
                            .ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        await _deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);
                    }
                }

                await _deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
        public async Task RunSampleAsync()
        {
            try
            {
                DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(
                    streamName: "TestStream"
                    );

                DeviceStreamResponse result;
                if (_moduleId != null)
                {
                    result = await _serviceClient.CreateStreamAsync(_deviceId, _moduleId, deviceStreamRequest).ConfigureAwait(false);
                }
                else
                {
                    result = await _serviceClient.CreateStreamAsync(_deviceId, deviceStreamRequest).ConfigureAwait(false);
                }

                Console.WriteLine("Stream response received: Name={0} IsAccepted={1}", deviceStreamRequest.StreamName, result.IsAccepted);

                if (result.IsAccepted)
                {
                    using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                        using (var stream = await DeviceStreamingCommon.GetStreamingClientAsync(result.Url, result.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                        {
                            byte[] sendBuffer    = Encoding.UTF8.GetBytes("Streaming data over a stream...");
                            byte[] receiveBuffer = new byte[1024];

                            await stream.SendAsync(sendBuffer, WebSocketMessageType.Binary, true, cancellationTokenSource.Token).ConfigureAwait(false);

                            Console.WriteLine("Sent stream data: {0}", Encoding.UTF8.GetString(sendBuffer, 0, sendBuffer.Length));

                            var receiveResult = await stream.ReceiveAsync(receiveBuffer, cancellationTokenSource.Token).ConfigureAwait(false);

                            Console.WriteLine("Received stream data: {0}", Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count));
                        }
                }
                else
                {
                    Console.WriteLine("Stream request was rejected by the device");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Got an exception: {0}", ex);
                throw;
            }
        }
Exemple #8
0
        private async Task RunSampleAsync(ModuleClient moduleClient, bool acceptDeviceStreamingRequest, CancellationTokenSource cancellationTokenSource)
        {
            Console.WriteLine("Creating DeviceStreamRequest");
            DeviceStreamRequest streamRequest = await moduleClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token).ConfigureAwait(false);

            if (streamRequest != null)
            {
                if (acceptDeviceStreamingRequest)
                {
                    await moduleClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);

                    using (ClientWebSocket webSocket = await DeviceStreamingCommon.GetStreamingClientAsync(streamRequest.Uri, streamRequest.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                    {
                        using (TcpClient tcpClient = new TcpClient())
                        {
                            await tcpClient.ConnectAsync(_hostName, _port).ConfigureAwait(false);

                            using (NetworkStream localStream = tcpClient.GetStream())
                            {
                                Console.WriteLine("Starting streaming");
                                await Task.WhenAny(
                                    HandleIncomingDataAsync(localStream, webSocket, cancellationTokenSource.Token),
                                    HandleOutgoingDataAsync(localStream, webSocket, cancellationTokenSource.Token)
                                    ).ConfigureAwait(false);

                                localStream.Close();
                            }
                        }

                        if (webSocket.State == WebSocketState.Open)
                        {
                            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationTokenSource.Token).ConfigureAwait(false);
                        }

                        Console.WriteLine($"{DateTime.UtcNow} - Streaming stopped");
                    }
                }
                else
                {
                    await moduleClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);
                }
            }
        }
Exemple #9
0
        public async Task RunSampleAsync(bool acceptDeviceStreamingRequest)
        {
            using (var cancellationTokenSource = new CancellationTokenSource(new TimeSpan(0, 5, 0)))
            {
                DeviceStreamRequest streamRequest = await _deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token).ConfigureAwait(false);

                if (streamRequest != null)
                {
                    if (acceptDeviceStreamingRequest)
                    {
                        await _deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);

                        using (ClientWebSocket webSocket = await DeviceStreamingCommon.GetStreamingClientAsync(streamRequest.Url, streamRequest.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                        {
                            using (TcpClient tcpClient = new TcpClient())
                            {
                                await tcpClient.ConnectAsync(_host, _port).ConfigureAwait(false);

                                using (NetworkStream localStream = tcpClient.GetStream())
                                {
                                    Console.WriteLine("Starting streaming");

                                    await Task.WhenAny(
                                        HandleIncomingDataAsync(localStream, webSocket, cancellationTokenSource.Token),
                                        HandleOutgoingDataAsync(localStream, webSocket, cancellationTokenSource.Token)).ConfigureAwait(false);

                                    localStream.Close();
                                }
                            }

                            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSource.Token).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        await _deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);
                    }
                }
            }
        }
Exemple #10
0
        private static async void HandleIncomingConnectionsAndCreateStreams(string deviceId, ServiceClient serviceClient, TcpClient tcpClient)
        {
            DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(
                streamName: "ProxyStreamFromSvc"
                );

            using (var localStream = tcpClient.GetStream())
            {
                Update("Awaiting connection");
                using (cancellationTokenSourceOuter = new CancellationTokenSource())
                {
                    DeviceStreamResponse result = await serviceClient.CreateStreamAsync(deviceId, deviceStreamRequest, cancellationTokenSourceOuter.Token).ConfigureAwait(false);

                    Update($"Stream response received: Name={deviceStreamRequest.StreamName} IsAccepted={result.IsAccepted}");

                    if (result.IsAccepted)
                    {
                        try
                        {
                            using (cancellationTokenSource = new CancellationTokenSource())
                                using (ClientWebSocket remoteStream = await DeviceStreamingCommon.GetStreamingClientAsync(result.Url, result.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                                {
                                    Update("Starting streaming");
                                    counter = 0;
                                    await Task.WhenAny(
                                        HandleIncomingDataAsync(localStream, remoteStream, cancellationTokenSource.Token),
                                        HandleOutgoingDataAsync(localStream, remoteStream, cancellationTokenSource.Token)).ConfigureAwait(false);
                                }

                            Update("Done streaming");
                        }
                        catch (Exception ex)
                        {
                            ErrorMsg("Service got an exception: {0}", ex);
                        }
                    }
                }
            }
            tcpClient.Close();
        }
        async Task <Option <(string requestName, IClientWebSocket clientWebSocket)> > WaitForStreamRequest(IModuleClient moduleClient)
        {
            var result = Option.None <(string, IClientWebSocket)>();

            try
            {
                DeviceStreamRequest deviceStreamRequest = await moduleClient.WaitForDeviceStreamRequestAsync(this.cts.Token);

                if (deviceStreamRequest != null)
                {
                    IClientWebSocket clientWebSocket = await moduleClient.AcceptDeviceStreamingRequestAndConnect(deviceStreamRequest, this.cts.Token);

                    result = Option.Some((deviceStreamRequest.Name, clientWebSocket));
                }
            }
            catch (Exception ex)
            {
                Events.ErrorGettingStream(ex);
            }

            return(result);
        }
        public async Task RunSampleAsync()
        {
            try
            {
                var deviceStreamRequest = new DeviceStreamRequest("TestStream");

                DeviceStreamResponse result = await _serviceClient.CreateStreamAsync(_deviceId, deviceStreamRequest);

                Console.WriteLine($"Stream response received: Name={deviceStreamRequest.StreamName} IsAccepted={result.IsAccepted}");

                if (result.IsAccepted)
                {
                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
                    using ClientWebSocket stream = await DeviceStreamingCommon.GetStreamingClientAsync(result.Uri, result.AuthorizationToken, cts.Token);

                    byte[] sendBuffer    = Encoding.UTF8.GetBytes("Streaming data over a stream...");
                    byte[] receiveBuffer = new byte[1024];

                    await stream.SendAsync(sendBuffer, WebSocketMessageType.Binary, true, cts.Token);

                    Console.WriteLine($"Sent stream data: {Encoding.UTF8.GetString(sendBuffer, 0, sendBuffer.Length)}");

                    var receiveResult = await stream.ReceiveAsync(receiveBuffer, cts.Token);

                    Console.WriteLine($"Received stream data: {Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count)}");

                    await stream.CloseAsync(WebSocketCloseStatus.NormalClosure, "Streaming completed", new CancellationToken());
                }
                else
                {
                    Console.WriteLine("Stream request was rejected by the device");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Got an exception: {ex}");
                throw;
            }
        }
        /// <summary>
        /// Handle incoming connections and create streams
        /// </summary>
        /// <param name="deviceId">device Id</param>
        /// <param name="serviceClient">service Client</param>
        /// <param name="tcpClient">TCP Client</param>
        private static async Task HandleIncomingConnectionsAndCreateStreams(string deviceId, ServiceClient serviceClient, TcpClient tcpClient)
        {
            DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(streamName: "TestStream");

            using (var localStream = tcpClient.GetStream())
            {
                DeviceStreamResponse result = await serviceClient.CreateStreamAsync(deviceId, deviceStreamRequest, CancellationToken.None).ConfigureAwait(false);

                if (result.IsAccepted)
                {
                    using (var cancellationTokenSource = new CancellationTokenSource())
                        using (var remoteStream = await DeviceStreamingHelper.GetStreamingClientAsync(result.Url, result.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                        {
                            await Task.WhenAny(
                                HandleIncomingDataAsync(localStream, remoteStream, cancellationTokenSource.Token),
                                HandleOutgoingDataAsync(localStream, remoteStream, cancellationTokenSource.Token)).ConfigureAwait(false);
                        }
                }
            }

            tcpClient.Close();
        }
        public async Task OpenConnectionAsync(IDeviceClient deviceClient, IClientWebSocket clientWebSocket, ITcpClient tcpClient, CancellationTokenSource cancellationTokenSource)
        {
            DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSource.Token).ConfigureAwait(false);

            if (streamRequest != null)
            {
                await deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);

                Console.WriteLine($"Device stream accepted from IoT Hub, at {DateTime.UtcNow}");

                clientWebSocket.Options.SetRequestHeader("Authorization", $"Bearer {streamRequest.AuthorizationToken}");

                await clientWebSocket.ConnectAsync(streamRequest.Url, cancellationTokenSource.Token).ConfigureAwait(false);

                Console.WriteLine($"Device stream connected to IoT Hub, at {DateTime.UtcNow}");

                await tcpClient.ConnectAsync(this.HostName, this.Port).ConfigureAwait(false);

                Console.WriteLine($"Device stream connected to local endpoint, at {DateTime.UtcNow}");

                using (var localStream = tcpClient.GetStream())
                {
                    await Task.WhenAny(
                        this.HandleIncomingDataAsync(clientWebSocket, localStream, cancellationTokenSource.Token),
                        this.HandleOutgoingDataAsync(clientWebSocket, localStream, cancellationTokenSource.Token)
                        ).ConfigureAwait(false);

                    localStream.Close();
                    Console.WriteLine($"Device stream closed to local endpoint, at {DateTime.UtcNow}");
                }

                await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSource.Token).ConfigureAwait(false);
            }
            else
            {
                await deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSource.Token).ConfigureAwait(false);
            }
        }
Exemple #15
0
        /// <summary>
        /// Initiates the device stream and maintains incoming and outgoing connections
        /// </summary>
        /// <param name="deviceId">The Id of the target device</param>
        /// <param name="tcpClient">The local TCP client</param>
        /// <param name="cancellationToken">Token used for cancelling this operation.</param>
        /// <returns>An awaitable async task</returns>
        private async Task ConnectStreamsAsync(string deviceId, TcpClient tcpClient, CancellationToken cancellationToken)
        {
            var request = new DeviceStreamRequest($"{deviceId}-{Guid.NewGuid()}");
            var result  = await serviceClient.CreateStreamAsync(deviceId, request, cancellationToken).ConfigureAwait(false);

            if (!result.IsAccepted)
            {
                return;
            }

            logger.LogInformation($"Starting a proxy connection to device {deviceId}");

            using var localStream  = tcpClient.GetStream();
            using var remoteStream = await GetStreamingClientAsync(result.Uri, result.AuthorizationToken, cancellationToken).ConfigureAwait(false);

            await Task.WhenAny(
                HandleIncomingDataAsync(localStream, remoteStream, cancellationToken),
                HandleOutgoingDataAsync(localStream, remoteStream, cancellationToken)).ConfigureAwait(false);

            logger.LogInformation($"Stopped a proxy connection with device {deviceId}");

            tcpClient.Close();
        }
        private static async void HandleIncomingConnectionsAndCreateStreams(string deviceId, ServiceClient serviceClient, TcpClient tcpClient)
        {
            DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(
                streamName: "TestStream"
                );

            using (var localStream = tcpClient.GetStream())
            {
                DeviceStreamResponse result = await serviceClient.CreateStreamAsync(deviceId, deviceStreamRequest, CancellationToken.None).ConfigureAwait(false);

                Console.WriteLine($"Stream response received: Name={deviceStreamRequest.StreamName} IsAccepted={result.IsAccepted}");

                if (result.IsAccepted)
                {
                    try
                    {
                        using (var cancellationTokenSource = new CancellationTokenSource(new TimeSpan(0, 1, 0)))
                            using (var remoteStream = await DeviceStreamingCommon.GetStreamingClientAsync(result.Url, result.AuthorizationToken, cancellationTokenSource.Token).ConfigureAwait(false))
                            {
                                Console.WriteLine("Starting streaming");

                                await Task.WhenAny(
                                    HandleIncomingDataAsync(localStream, remoteStream, cancellationTokenSource.Token),
                                    HandleOutgoingDataAsync(localStream, remoteStream, cancellationTokenSource.Token)).ConfigureAwait(false);
                            }

                        Console.WriteLine("Done streaming");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Got an exception: {0}", ex);
                    }
                }
            }
            tcpClient.Close();
        }
 public Task RejectDeviceStreamRequestAsync(DeviceStreamRequest request, CancellationToken cancellationToken)
 {
     return(this.deviceClient.RejectDeviceStreamRequestAsync(request, cancellationToken));
 }
        private async Task RunSvcAsync()
        {
            string errorMsg  = "";
            string updateMsg = "";

            using (cancellationTokenSourceManual = new CancellationTokenSource())
            {
                ClientWebSocket stream = null;
                try
                {
                    DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(
                        streamName: "TestStream"
                        );
                    updateMsg = "Starting Svc TestStream";
                    UpdateStatus(updateMsg);

                    cancellationTokenSourceManual.Token.Register(() =>
                    {
                        _serviceClient?.CloseAsync();
                        _serviceClient?.Dispose();
                    });

                    DeviceStreamResponse result = await _serviceClient.CreateStreamAsync(_deviceId, deviceStreamRequest).ConfigureAwait(false);

                    updateMsg = string.Format("Svc Stream response received: Name={0} IsAccepted={1}", deviceStreamRequest.StreamName, result.IsAccepted);
                    UpdateStatus(updateMsg);

                    if (result.IsAccepted)
                    {
                        using (cancellationTokenSourceTimeout = new CancellationTokenSource(DeviceStreamingCommon.DeviceTimeout))
                        {
                            try
                            {
                                using (stream = await DeviceStreamingCommon.GetStreamingDeviceAsync(result.Url, result.AuthorizationToken, cancellationTokenSourceTimeout.Token).ConfigureAwait(false))
                                {
                                    updateMsg = "Stream is open.";
                                    UpdateStatus(updateMsg);
                                    bool keepAlive = false;
                                    MsgOutWaitHandle = new AutoResetEvent(true);
                                    do
                                    {
                                        //Nb: Not waited on first entry as waiting for msgOut, which we already have.
                                        updateMsg = "Stream is open. Waiting for msg to send.";
                                        UpdateStatus(updateMsg);

                                        MsgOutWaitHandle.WaitOne();
                                        updateMsg = "Sending msg.";
                                        UpdateStatus(updateMsg);
                                        bool caught = false;
                                        try
                                        {
                                            MsgOut = SvcCurrentSettings.ProcessMsgOut(MsgOut, SvcCurrentSettings.KeepAlive, SvcCurrentSettings.ResponseExpected, DevKeepListening, DevAutoStart);
                                        } catch (NotImplementedException)
                                        {
                                            errorMsg += "DeviceCurrentSettings not properly implemented";
                                            keepAlive = false;
                                            caught    = true;
                                        }
                                        if (!caught)
                                        {
                                            await SendMsg(stream, MsgOut, cancellationTokenSourceTimeout);

                                            updateMsg = "Sent msg.";
                                            UpdateStatus(updateMsg);

                                            if (this.SvcCurrentSettings.ResponseExpected)
                                            {
                                                byte[] receiveBuffer = new byte[1024];
                                                System.ArraySegment <byte> ReceiveBuffer = new ArraySegment <byte>(receiveBuffer);

                                                var receiveResult = await stream.ReceiveAsync(ReceiveBuffer, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                                MsgIn = Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count);
                                                string subStrn    = AzIoTHubDeviceStreams.DeviceStreamingCommon.DeiceInSimuatedDeviceModeStrn;
                                                int    subStrnLen = subStrn.Length;
                                                if (MsgIn.Length >= subStrnLen)
                                                {
                                                    if (MsgIn.Substring(0, subStrnLen) == subStrn)
                                                    {
                                                        MsgIn = MsgIn.Substring(subStrnLen);
                                                        AzIoTHubModules.SyntheticIoTMessage    iotHubMessage = AzIoTHubModules.SyntheticIoTMessage.Deserialize(MsgIn);
                                                        Microsoft.Azure.Devices.Client.Message message       = iotHubMessage.ToMessage();
                                                        Microsoft.Azure.EventHubs.EventData    eventData     = AzIoTHubModules.SyntheticIoTMessage.ToEventData(message);
                                                        MsgIn = AzIoTHubModules.SyntheticIoTMessage.EventData_ToString(eventData);
                                                    }
                                                }
                                                keepAlive = false;
                                                if (SvcCurrentSettings != null)
                                                {
                                                    keepAlive = this.SvcCurrentSettings.KeepAlive;
                                                }
                                                try
                                                {
                                                    if (OnRecvdTextD != null)
                                                    {
                                                        OnRecvdTextD(MsgIn);
                                                    }
                                                }
                                                catch (Exception exx)
                                                {
                                                    errorMsg += "OnRecvdTextD not properly implemented: " + exx.Message;
                                                    keepAlive = false;
                                                }

                                                updateMsg = string.Format("Svc Received stream data: {0}", MsgIn);
                                                UpdateStatus(updateMsg);
                                            }
                                            MsgOutWaitHandle.Reset();
                                        }
                                    } while (keepAlive);
                                    MsgOutWaitHandle = null;
                                    updateMsg        = "Closing Svc Socket";
                                    UpdateStatus(updateMsg);
                                    await stream.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                    stream = null;
                                }
                            }
                            catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Hub connection failure");
                                errorMsg = "Hub connection failure";
                            }
                            catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Device not found");
                                errorMsg = "Device not found";
                            }
                            catch (TaskCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Task cancelled");
                                errorMsg = "Task cancelled";
                            }
                            catch (OperationCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Operation cancelled");
                                errorMsg = "Operation cancelled";
                            }
                            catch (Exception ex)
                            {
                                if ((bool)cancellationTokenSourceManual?.IsCancellationRequested)
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Cancelled.");
                                    errorMsg = "Cancelled";
                                }
                                else if ((bool)cancellationTokenSourceTimeout?.IsCancellationRequested)
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Timed Out.");
                                    errorMsg = "Timed Out";
                                }
                                else if (!ex.Message.Contains("Timed out"))
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): " + ex.Message);
                                    errorMsg = ex.Message;
                                }
                                else
                                {
                                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed out");
                                    errorMsg = "Timed Out";
                                }
                            }
                        }
                    }
                }
                catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Hub connection failure");
                    errorMsg += " Hub connection failure";
                }
                catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Device not found");
                    errorMsg += " Device not found";
                }
                catch (TaskCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Task cancelled");
                    errorMsg += " Task cancelled";
                }
                catch (OperationCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Operation cancelled");
                    errorMsg += " Operation cancelled";
                }
                catch (Exception ex)
                { if ((bool)cancellationTokenSourceManual?.IsCancellationRequested)
                  {
                      System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Cancelled.");
                      errorMsg += " Cancelled";
                  }
                  else if ((bool)cancellationTokenSourceTimeout?.IsCancellationRequested)
                  {
                      System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed Out.");
                      errorMsg += " Timed Out";
                  }
                  else if (!ex.Message.Contains("Timed out"))
                  {
                      System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): " + ex.Message);
                      errorMsg += " " + ex.Message;
                  }
                  else
                  {
                      System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed out");
                      errorMsg += " Timed Out";
                  } };

                if (stream != null)
                {
                    if (stream.CloseStatus != WebSocketCloseStatus.NormalClosure)
                    {
                        updateMsg = "Aborting Svc Socket as is errant or cancelled: " + errorMsg;
                        UpdateStatus(updateMsg);
                        stream.Abort();
                        updateMsg = "Aborted Svc Socket as was errant or cancelled:" + errorMsg;
                        UpdateStatus(updateMsg);
                    }
                    else
                    {
                        updateMsg = "Socket closed normally: " + errorMsg;
                        UpdateStatus(updateMsg);
                    }
                    stream = null;
                }
                else
                {
                    updateMsg = "Socket closed Normally: " + errorMsg;
                    UpdateStatus(updateMsg);
                }

                deviceStream_Svc = null;
                MsgOutWaitHandle = null;
                cancellationTokenSourceTimeout = null;
            }
        }
        public async Task HandleRequestTest()
        {
            // Arrange
            var deviceStreamRequest1 = new DeviceStreamRequest("req1", "Type1", new Uri("http://dummyurl"), Guid.NewGuid().ToString());
            var deviceStreamRequest2 = new DeviceStreamRequest("req2", "Type2", new Uri("http://dummyurl"), Guid.NewGuid().ToString());
            var deviceStreamRequest3 = new DeviceStreamRequest("req3", "Type3", new Uri("http://dummyurl"), Guid.NewGuid().ToString());

            var clientWebSocket1 = new Mock <IClientWebSocket>();
            var clientWebSocket2 = new Mock <IClientWebSocket>();
            var clientWebSocket3 = new Mock <IClientWebSocket>();

            var moduleClient = new Mock <IModuleClient>();

            moduleClient.SetupSequence(m => m.WaitForDeviceStreamRequestAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(deviceStreamRequest1)
            .ReturnsAsync(deviceStreamRequest2)
            .ReturnsAsync(deviceStreamRequest3);

            moduleClient.Setup(m => m.AcceptDeviceStreamingRequestAndConnect(deviceStreamRequest1, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(clientWebSocket1.Object));
            moduleClient.Setup(m => m.AcceptDeviceStreamingRequestAndConnect(deviceStreamRequest2, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(clientWebSocket2.Object));
            moduleClient.Setup(m => m.AcceptDeviceStreamingRequestAndConnect(deviceStreamRequest3, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(clientWebSocket3.Object));

            var requestHandler1TaskCompletionSource = new TaskCompletionSource <bool>();
            var streamRequestHandlerType1Mock       = new Mock <IStreamRequestHandler>();

            streamRequestHandlerType1Mock.Setup(s => s.Handle(clientWebSocket1.Object, It.IsAny <CancellationToken>()))
            .Returns(requestHandler1TaskCompletionSource.Task);

            var requestHandler2TaskCompletionSource = new TaskCompletionSource <bool>();
            var streamRequestHandlerType2Mock       = new Mock <IStreamRequestHandler>();

            streamRequestHandlerType2Mock.Setup(s => s.Handle(clientWebSocket2.Object, It.IsAny <CancellationToken>()))
            .Returns(requestHandler2TaskCompletionSource.Task);

            var requestHandler3TaskCompletionSource = new TaskCompletionSource <bool>();
            var streamRequestHandlerType3Mock       = new Mock <IStreamRequestHandler>();

            streamRequestHandlerType3Mock.Setup(s => s.Handle(clientWebSocket3.Object, It.IsAny <CancellationToken>()))
            .Returns(requestHandler3TaskCompletionSource.Task);

            IStreamRequestHandler streamRequestHandlerType1 = streamRequestHandlerType1Mock.Object;
            IStreamRequestHandler streamRequestHandlerType2 = streamRequestHandlerType2Mock.Object;
            IStreamRequestHandler streamRequestHandlerType3 = streamRequestHandlerType3Mock.Object;

            var streamRequestHandlerProvider = new Mock <IStreamRequestHandlerProvider>();

            streamRequestHandlerProvider.Setup(s => s.TryGetHandler("Type1", out streamRequestHandlerType1)).Returns(true);
            streamRequestHandlerProvider.Setup(s => s.TryGetHandler("Type2", out streamRequestHandlerType2)).Returns(true);
            streamRequestHandlerProvider.Setup(s => s.TryGetHandler("Type3", out streamRequestHandlerType3)).Returns(true);

            var streamRequestListener = new StreamRequestListener(streamRequestHandlerProvider.Object, 2);

            // Act
            streamRequestListener.InitPump(moduleClient.Object);

            // Assert
            await Task.Delay(TimeSpan.FromSeconds(5));

            streamRequestHandlerType1Mock.Verify(s => s.Handle(clientWebSocket1.Object, It.IsAny <CancellationToken>()), Times.Once);
            streamRequestHandlerType2Mock.Verify(s => s.Handle(clientWebSocket2.Object, It.IsAny <CancellationToken>()), Times.Once);
            streamRequestHandlerType3Mock.Verify(s => s.Handle(clientWebSocket3.Object, It.IsAny <CancellationToken>()), Times.Never);

            requestHandler1TaskCompletionSource.SetResult(true);
            await Task.Delay(TimeSpan.FromSeconds(5));

            streamRequestHandlerType1Mock.Verify(s => s.Handle(clientWebSocket1.Object, It.IsAny <CancellationToken>()), Times.Once);
            streamRequestHandlerType2Mock.Verify(s => s.Handle(clientWebSocket2.Object, It.IsAny <CancellationToken>()), Times.Once);
            streamRequestHandlerType3Mock.Verify(s => s.Handle(clientWebSocket3.Object, It.IsAny <CancellationToken>()), Times.Once);

            requestHandler2TaskCompletionSource.SetResult(true);
            requestHandler3TaskCompletionSource.SetResult(true);

            moduleClient.VerifyAll();
            streamRequestHandlerProvider.VerifyAll();
        }
Exemple #20
0
        public async Task <IClientWebSocket> AcceptDeviceStreamingRequestAndConnect(DeviceStreamRequest deviceStreamRequest, CancellationToken cancellationToken)
        {
            await this.moduleClient.AcceptDeviceStreamRequestAsync(deviceStreamRequest, cancellationToken);

            return(await EdgeClientWebSocket.Connect(deviceStreamRequest.Url, deviceStreamRequest.AuthorizationToken, cancellationToken));
        }