Azure Function和SignalR Service 向 Web 前端推送IoT 報警信息

本文介紹:

Azure Function和SignalR Service 向 Web 前端推送IoT 報警信息 (C#)

 

 

視頻介紹:

https://www.51azure.cloud/post/2020/6/16/azure-iot-hub-15-azure-function-signalr-service-push-message

將物聯網報警數據推送到web前端

 

 

圖文介紹:

注意,本文在  《實現Azure Function 通過IoT Hub Trigger將遙測消息寫入SQL數據庫(C#)》的基礎上繼續進行。

 

本文參照案例:https://docs.microsoft.com/zh-cn/azure/azure-signalr/signalr-quickstart-azure-functions-csharp

本文使用的示例代碼:https://github.com/Azure-Samples/signalr-service-quickstart-serverless-chat

 

創建SignalR Service:

 

填寫信息,完成創建:

 

找到SignalR 連接字符串:

修改上一講的示例代碼如下:

using IoTHubTrigger = Microsoft.Azure.WebJobs.EventHubTriggerAttribute;

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Azure.EventHubs;
using System.Text;
using System.Net.Http;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

using System.Data;
using System.Data.SqlClient;
using System;
using Newtonsoft.Json;

using System.Net;
using System.IO;


using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;

namespace Company.Function
{
    public static class iothubtriggertodb
    {
        private static HttpClient client = new HttpClient();

        [FunctionName("iothubtriggertodb")]
        public static void Run(
            [IoTHubTrigger("messages/events", Connection = "IotHubEventHubString")]EventData message,
            [SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages,
            ILogger log)
        {
            log.LogInformation($"C# IoT Hub trigger function processed a message: {Encoding.UTF8.GetString(message.Body.Array)}");

            var deviceid=message.SystemProperties["iothub-connection-device-id"].ToString();

            
            var dbstring=System.Environment.GetEnvironmentVariable("SQLConn");
            
            Telemetry tmsg = JsonConvert.DeserializeObject<Telemetry>(Encoding.UTF8.GetString(message.Body.Array));



            tmsg.funcsavedt = DateTime.Now;
            tmsg.deviceid = deviceid;

            try
            {

                //blow code are using to save data to sql db

                using (SqlConnection con = new SqlConnection(dbstring))
                {
                    con.Open();
                    if (con.State == ConnectionState.Open)
                    {
                        string strCmd = $"insert into dbo.Telemetry(temperature,humidity,funcsavedt,deviceid) values ({tmsg.temperature},{tmsg.humidity},'{System.DateTime.Now}','{deviceid}' )";


                        SqlCommand sqlcmd = new SqlCommand(strCmd, con);
                        int n = sqlcmd.ExecuteNonQuery();
                        if (n > 0)
                        {
                            log.LogInformation("save to db successfully");
                        }
                        else
                        {
                            log.LogError("save to db error");
                        }

                    }
                    con.Close();
                }
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
            }



           // azure functions output binding, send iot data to signalr, then push to frontend web.
            signalRMessages.AddAsync(
                 new SignalRMessage
                 {
                     // newMessage is a function, web client should handle.
                     Target = "newMessage",
                     Arguments = new[] { new { sender=$"iot hub function from cloud-{DateTime.Now}", text=$"deviceid-{deviceid.Substring(0,10)},temperature:{tmsg.temperature},humidity:{tmsg.humidity}"} }
                 });
        }



        # region these two functions just want to show your how signalr service work 
         
        
        [FunctionName("negotiate")]
        public static SignalRConnectionInfo GetSignalRInfo(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [SignalRConnectionInfo(HubName = "chat")] SignalRConnectionInfo connectionInfo)
        {
            return connectionInfo;
        }

        [FunctionName("messages")]
        public static Task SendMessage(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] object message,
            [SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages)
        {
            return signalRMessages.AddAsync(
                new SignalRMessage
                {
                    Target = "newMessage",
                    Arguments = new[] { message }
                });
        }

        #endregion 
    }    



    public class Telemetry
        {
            public string deviceid{get;set;}

            public DateTime funcsavedt{get;set; }
            public double temperature { get; set; }

            public double humidity { get; set; }
    }
}

 

local.setting.json:

其中,如果將HTML部署到本地,則需要將CORS中增加:http://localhost:80或者對應的端口的URL

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "{your webjob storage connection string}",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "AzureSignalRConnectionString": "{your signalr connection string}",
    "SQLConn": "Data Source =XXX.database.windows.net;Initial Catalog =DBName;User Id =xxx;Password =xxx;"
  },
  "Host": {
    "LocalHttpPort": 7071,
    "CORS": "http://localhost:8080,https://azure-samples.github.io",
    "CORSCredentials": true
  }
}

 

ctrl+shift+p,將Functions 發佈,

發佈完成後,將SignalR的連接字符串配置到Functions中:

如果前端頁面採用 https://azure-samples.github.io/signalr-service-quickstart-serverless-chat/demo/chat-v2/ 的示例頁面,則需要將其添加到Functions 的CORS配置中:

 

將HTML頁面託管到Storage中(本步驟是可選的,也可以部署到您自己的服務器上)

創建一個Storage Account

 

開啓Storage Account 的靜態網站功能:

注意,其中的主終結點名稱即爲 要訪問的URL。

 

將示例Html頁面上傳到 Storage Account 中自動生成的$WEB 容器中:

 

配置Functions 的CORS:

將Storage 靜態站點的主終結點添加到CORS中,將末尾的"/"去掉,勾選 啓用Allow-control-allow-credentials

 

至此,配置部分完成,打開Storage Account 的主終結點,開啓IOT 設備,可以看到數據正常推送到也web頁面上:

填寫Functions 的 URL:

 

如下圖,可以看到遙測的溫溼度在頁面上刷新:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章