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); }); }
/// <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()}"); } } }
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; } }
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); } } }
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); } } } }
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); } }
/// <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(); }
public async Task <IClientWebSocket> AcceptDeviceStreamingRequestAndConnect(DeviceStreamRequest deviceStreamRequest, CancellationToken cancellationToken) { await this.moduleClient.AcceptDeviceStreamRequestAsync(deviceStreamRequest, cancellationToken); return(await EdgeClientWebSocket.Connect(deviceStreamRequest.Url, deviceStreamRequest.AuthorizationToken, cancellationToken)); }