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; } }