示例#1
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);
            }
        }
示例#3
0
        public static async Task RegisterDeviceStreamCallback(this DeviceClient moduleClient, Func <ClientWebSocket, CancellationToken, Task> callback, CancellationToken ct)
        {
            int sleeptime = 1000;

            // This will run until the cancelation token is canceled
            while (!ct.IsCancellationRequested)
            {
                Console.WriteLine("Waiting for connection request");
                DeviceStreamRequest request;
                try
                {
                    request = await moduleClient.WaitForDeviceStreamRequestAsync(ct);

                    Console.WriteLine("Got connection request");
                    await moduleClient.AcceptDeviceStreamRequestAsync(request, ct).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Request got exeption:");
                    Console.WriteLine(ex);

                    Console.WriteLine($"Trying again in {sleeptime} seconds.");
                    await Task.Delay(sleeptime);

                    /* Max sleeptime is 10 minutes */
                    if (sleeptime < 1000 * 60 * 10)
                    {
                        sleeptime *= 2;
                    }
                    continue;
                }
                sleeptime = 1000;

                using (ClientWebSocket webSocket = await DeviceStreamWebsocket.MakeWebSocket(request.Url, request.AuthorizationToken, ct))
                {
                    try
                    {
                        await callback(webSocket, ct);
                    }
                    catch (WebSocketException ex)
                    {
                        Console.WriteLine("Websocket threw exception.");
                        Console.WriteLine(ex);
                    }

                    Console.WriteLine("Finished Connection Request");
                }

                Console.WriteLine("Closing websocket");
            }
        }
        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()}");
                }
            }
        }
示例#5
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);
            }
        }
示例#6
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);
                    }
                }
            }
        }
        /// <summary>
        /// The actual Device Streaming method at Device end of the pipe
        /// </summary>
        /// <param name="acceptDeviceStreamingRequest"></param>
        /// <returns></returns>
        private async Task RunDeviceAsync(bool acceptDeviceStreamingRequest)
        {
            isManualCancel = false;
            string errorMsg  = "";
            string updateMsg = "";

            byte[]          buffer    = new byte[1024];
            ClientWebSocket webSocket = null;

            byte[] sendBuffer;
            try
            {
                using (cancellationTokenSourceTimeout = new CancellationTokenSource(DeviceStreamingCommon.DeviceTimeout))
                {
                    try
                    {
                        cancellationTokenSourceTimeout.Token.Register(() =>
                        {
                            webSocket?.Abort();
                            webSocket?.Dispose();
                        });
                        updateMsg = "Starting Device Stream Request.";
                        System.Diagnostics.Debug.WriteLine(updateMsg);
                        UpdateStatus(updateMsg);

                        Microsoft.Azure.Devices.Client.DeviceStreamRequest streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

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

                                updateMsg = "Device got a connection.";
                                UpdateStatus(updateMsg);

                                using (webSocket = await DeviceStreamingCommon.GetStreamingClientAsync(streamRequest.Url, streamRequest.AuthorizationToken, cancellationTokenSourceTimeout.Token).ConfigureAwait(false))
                                {
                                    updateMsg = string.Format("Device got stream: Name={0}. Socket open.", streamRequest.Name);
                                    UpdateStatus(updateMsg);


                                    bool keepAlive = false;
                                    do
                                    {
                                        updateMsg = string.Format("Device is connected and listening");
                                        UpdateStatus(updateMsg);
                                        WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                        if (receiveResult.MessageType == WebSocketMessageType.Close)
                                        {
                                            UpdateStatus("Received Close msg");
                                            keepAlive = false;
                                        }
                                        else
                                        {
                                            string MsgIn = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);


                                            //If the received text is more than one line only use the first line
                                            string[] lines = MsgIn.Split(new char[] { '\r', '\n' });
                                            if (lines.Length > 1)
                                            {
                                                MsgIn = lines[0];
                                            }

                                            updateMsg = string.Format("Device Received stream data: {0}.", MsgIn);
                                            UpdateStatus(updateMsg);

                                            //Get keepAlive and respond flags and strip from msg in
                                            bool respond = true;
                                            try
                                            {
                                                MsgIn     = DeviceCurrentSettings.ProcessMsgIn(MsgIn);
                                                respond   = DeviceCurrentSettings.ResponseExpected;
                                                keepAlive = DeviceCurrentSettings.KeepAlive;
                                                if (DeviceCurrentSettings.AutoStartDeviceChanged)
                                                {
                                                    ActionCmdD?.Invoke(DeviceCurrentSettings.AutoStartDevice, "", 0, 0);
                                                }
                                                if (DeviceCurrentSettings.KeepDeviceListeningChanged)
                                                {
                                                    ActionCmdD?.Invoke(DeviceCurrentSettings.KeepDeviceListening, "", 0, 1);
                                                }
                                            }
                                            catch (System.NotImplementedException)
                                            {
                                                errorMsg += "DeviceCurrentSettings not properly Implemented";
                                                keepAlive = false;
                                                respond   = false;
                                            }

                                            string  msgOut      = MsgIn;
                                            Message sendMessage = null;
                                            try
                                            {
                                                if (OnRecvdTextIO != null)
                                                {
                                                    msgOut = OnRecvdTextIO(MsgIn, out sendMessage);
                                                }
                                            }
                                            catch (Exception exx)
                                            {
                                                errorMsg += "OnRecvdTextIO not properly Implemented: " + exx.Message;
                                                keepAlive = false;
                                                respond   = false;
                                            }

                                            if (respond)
                                            {
                                                //if (sendMessage == null)
                                                //{
                                                sendBuffer = Encoding.UTF8.GetBytes(msgOut);
                                                await webSocket.SendAsync(new ArraySegment <byte>(sendBuffer, 0, sendBuffer.Length), WebSocketMessageType.Binary, true, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                                //}
                                                //else
                                                //{

                                                //    sendBuffer = sendMessage.GetBytes();
                                                //    var xx = new ArraySegment<byte>(sendBuffer, 0, sendBuffer.Length);
                                                //    byte[] longer = xx.Array;
                                                //    byte[] shortArray = longer.Take(sendBuffer.Length).ToArray();
                                                //    Microsoft.Azure.Devices.Client.Message message = null;
                                                //    message = new Microsoft.Azure.Devices.Client.Message(shortArray);
                                                //    await webSocket.SendAsync(xx, WebSocketMessageType.Binary, true, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);
                                                //}

                                                updateMsg = string.Format("Device Sent stream data: {0}", Encoding.UTF8.GetString(sendBuffer, 0, sendBuffer.Length));
                                                UpdateStatus(updateMsg);
                                            }
                                            //By default do not loop
                                        }
                                    } while (keepAlive);

                                    updateMsg = "Closing Device Socket Normally.";
                                    UpdateStatus(updateMsg);
                                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                    webSocket = null;
                                }
                            }
                            else
                            {
                                await deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);
                            }
                        }

                        await deviceClient.CloseAsync().ConfigureAwait(false);
                    }
                    catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                    {
                        if ((bool)cancellationTokenSourceTimeout?.IsCancellationRequested)
                        {
                            System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Timed Out.");
                            errorMsg += " Timed Out";
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("1 Error RunDeviceAsync(): Hub connection failure");
                            errorMsg = "Hub connection failure";
                        }
                    }
                    catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                    {
                        System.Diagnostics.Debug.WriteLine("1 Error RunDeviceAsync(): Device not found");
                        errorMsg = "Device not found";
                    }
                    catch (TaskCanceledException)
                    {
                        System.Diagnostics.Debug.WriteLine("1 Error RunDeviceAsync(): Task cancelled");
                        errorMsg = "Task cancelled";
                    }
                    catch (OperationCanceledException eex)
                    {
                        System.Diagnostics.Debug.WriteLine("1 Error RunDeviceAsync(): Operation cancelled \r\n" + eex.Message);
                        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("1 Error RunSvcAsync(): Timed out");
                            errorMsg += " Timed Out";
                        }
                    }
                }
            }
            catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
            {
                System.Diagnostics.Debug.WriteLine("2 Error RunDeviceAsync(): Hub connection failure");
                errorMsg = "Hub connection failure";
            }
            catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
            {
                System.Diagnostics.Debug.WriteLine("2 Error RunDeviceAsync(): Device not found");
                errorMsg = "Device not found";
            }
            catch (TaskCanceledException)
            {
                System.Diagnostics.Debug.WriteLine("2 Error RunDeviceAsync(): Task cancelled");
                errorMsg = "Task cancelled";
            }
            catch (OperationCanceledException eex)
            {
                System.Diagnostics.Debug.WriteLine("2 Error RunDeviceAsync(): Operation cancelled \r\n" + eex.Message);
                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 (webSocket != null)
            {
                if (webSocket.CloseStatus != WebSocketCloseStatus.NormalClosure)
                {
                    updateMsg = "Aborting Device Socket as is errant or cancelled: " + errorMsg;
                    UpdateStatus(updateMsg);
                    webSocket.Abort();
                    updateMsg = "Aborted Device Socket as was errant or cancelled: " + errorMsg;
                    UpdateStatus(updateMsg);
                }
                else
                {
                    updateMsg = "Socket closed normally: " + errorMsg;
                    UpdateStatus(updateMsg);
                }
            }
            else
            {
                if (isManualCancel)
                {
                    updateMsg = "Socket closed Normally: Manually ";
                }
                else
                {
                    updateMsg = "Socket closed Normally: " + errorMsg;
                }
                UpdateStatus(updateMsg);
            }
            webSocket = null;
            cancellationTokenSourceTimeout = null;
        }