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.GetStreamingClientAsync(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 = Azure_IoTHub_DeviceStreaming.DeviceStreamingCommon.DeviceInSimuatedDeviceModeStrn; int subStrnLen = subStrn.Length; string subStrn2 = Azure_IoTHub_Sensors.TelemetryDataPoint.Prefix; int subStrnLen2 = subStrn2.Length; if (MsgIn.Length>= subStrnLen) if (MsgIn.Substring(0,subStrnLen) == subStrn) { MsgIn = MsgIn.Substring(subStrnLen); Azure_IoTHub_Telemetry.SyntheticIoTMessage iotHubMessage = Azure_IoTHub_Telemetry.SyntheticIoTMessage.Deserialize(MsgIn); Microsoft.Azure.Devices.Client.Message message = iotHubMessage.ToMessage(); Microsoft.Azure.EventHubs.EventData eventData = Azure_IoTHub_Telemetry.SyntheticIoTMessage.ToEventData(message); MsgIn = Azure_IoTHub_Telemetry.SyntheticIoTMessage.EventData_ToString(eventData); } else if (MsgIn.Length >= subStrnLen2) if (MsgIn.Substring(0, subStrnLen2) == subStrn2) { MsgIn = MsgIn.Substring(subStrnLen2); Azure_IoTHub_Sensors.TelemetryDataPoint telemetry = Azure_IoTHub_Sensors.TelemetryDataPoint.Deserialize(MsgIn); MsgIn = telemetry.ToString(); //Microsoft.Azure.Devices.Client.Message message = iotHubMessage.ToMessage(); //Microsoft.Azure.EventHubs.EventData eventData = Azure_IoTHub_Telemetry.SyntheticIoTMessage.ToEventData(message); //MsgIn = Azure_IoTHub_Telemetry.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; } }
// Async method to send simulated telemetry private static async Task SendDeviceToCloudMessagesAsync() { // Initial telemetry values //double minTemperature = 20; //double minHumidity = 60; //Random rand = new Random(); OnDeviceStatusUpdateD?.Invoke("IoT Hub Telemetry #2- Device sending messages."); ContinueLoop = true; while (ContinueLoop) { //double currentTemperature = minTemperature + rand.NextDouble() * 15; //double currentHumidity = minHumidity + rand.NextDouble() * 20; //// Create JSON message //var telemetryDataPoint = new //{ // temperature = currentTemperature, // humidity = currentHumidity //}; //var messageString = JsonConvert.SerializeObject(telemetryDataPoint); //var message = new Message(Encoding.ASCII.GetBytes(messageString)); //// Add a custom application property to the message. //// An IoT hub can filter on these properties without access to the message body. //message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false"); //await s_deviceClient.SendEventAsync(message); Azure_IoTHub_Sensors.TelemetryDataPoint telemetryDataPoint; if (Azure_IoTHub_Sensors.Weather.CurrentWeather.DoAsync) { telemetryDataPoint = await Azure_IoTHub_Sensors.Weather.CurrentWeather.GetWeatherAsync(); } else { telemetryDataPoint = Azure_IoTHub_Sensors.Weather.CurrentWeather.GetWeather(); } MessageString = JsonConvert.SerializeObject(telemetryDataPoint); Message = new Message(Encoding.ASCII.GetBytes(MessageString)); //Message.UserId = Azure_IoTHub_Connections.MyConnections.IoTHubName; Message.Properties.Add("temperatureAlert", (telemetryDataPoint.temperature > 30) ? "true" : "false"); Message.Properties.Add("humidityAlert", (telemetryDataPoint.humidity > 80) ? "true" : "false"); Message.Properties.Add("pressureAlert", (telemetryDataPoint.pressure > 1010) ? "true" : "false"); Azure_IoTHub_Telemetry.SyntheticIoTMessage iotmessage = new Azure_IoTHub_Telemetry.SyntheticIoTMessage(Message); MessageString = iotmessage.Serialise(); SetDeviceSentMsg?.Invoke(string.Format("{0} > Sending message: {1}", DateTime.Now, MessageString)); // Send the tlemetry message await s_deviceClient.SendEventAsync(Message); SetDeviceSentMsg?.Invoke(string.Format("{0} > Sending message: {1}", DateTime.Now, MessageString)); s_telemetryInterval = Azure_IoTHub_Connections.MyConnections.TelemetryDelayBtwReadings; await Task.Delay(s_telemetryInterval * 1000); if (!ContinueLoop) { OnDeviceStatusUpdateD?.Invoke("Cancelled Telemetry - Device end"); } } }