[IoT] Azure IoT整合應用三:建立WebJob,接收從IoT Hub的訊息並進行處理

  • 1397
  • 0
  • IoT
  • 2016-11-06

在前一篇文章[Azure] Azure IoT整合應用二:建立串流分析工作,接收從IoT Hub的訊息並進行處理
說明了如何透過串流分析取得IoT Hub的資料並傳出至其他的服務中,當然若是運作的規則或是邏輯過於複雜的情況,也可以透過寫程式的方式完成

要透過寫程式的方式,取得IoT Hub的內容,並加以處理的話,就必須將寫好的程式佈署到WebApp中的WebJob之中

在開始寫之前,請先在電腦上安裝Azure SDK,下載的網址在這裡
Microsoft Azure SDK

1.安裝Microsoft Azure SDK,下載安裝檔並安裝後,在Microsoft Web Platform Installer中,選擇安裝[Microsoft Azure PowerShell][Microsoft Azure SDK for .NET]

2.在Azure上先建立一個WebApp,可以先給予一個名稱,等未來寫好的程式會放在這個WebApp上的webJob中執行

3.在Visual Studio中建立一個新專案,建立專案的範本,請選擇[Azure WebJob],並給予一個專案名稱

4.由於是要透過程式碼取得IoT Hub的資料,所以先進到IoT Hub中,傳訊的選項裡,加入一個[取用者群組],另外加入取用者群組的原因,主要是為了與串流分析取用資料的動作作分開,才不會用同一組群組作資料的取得

5.回到Visual Studio中,在剛建立好的專案,加入下面清單中的Nuget套件

WindowsAzure.ServiceBus
Microsoft.Azure.ServiceBus.EventProcessorHost

裝好之後,同時也會加入一些其他元件的參考進入這個WebJob的專案中

6.由於是透過程式讀取IoT Hub,所以有一些可以參考的寫法。我在這裡只列出重點,若是有興趣的人可以參考GitHub上的專案檔,或是連至參考網頁查看相關資訊

  • 建立一個IoTProcessor.cs在專案中,並繼承[IEventProcessor]這個介面
  • 加入三個事件,分別為
    public Task CloseAsync(PartitionContext context, CloseReason reason)
    public Task OpenAsync(PartitionContext context)
    async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)

這三個事件是必須要加入進程式碼的,因為要讀取IoT Hub上的訊息,就是依賴這三個事件來處理,分別是當連線關閉,開啟以及同步處理的動作

7.在這裡先加上連線至IoT Hub的連線字串,方便程式碼進行連線的動作,而在這一個WebJob的執行過程中,有可能會將IoT Hub取得的資料送至資料庫或是Service Bus,有需要的人可以依需求加入相對應的程式碼

class IoTProcessor : IEventProcessor
{
    public static string StorageConnectionString { get; set; }
    public static string ServiceBusConnectionString { get; set; }
    public static string DatabaseConnectString { get; set; }
}

8.接著在
OpenAsync的副程式中加入下面的程式碼

stopwatch = new Stopwatch();
stopwatch.Start();
return Task.FromResult<object>(null);

CloseAsync的部份加上這段程式碼

return Task.FromResult<object>(null);

ProcessEventsAsync的部份加上下面這段程式碼

foreach (EventData eventData in messages)
{
    byte[] data = eventData.GetBytes();

    var text = Encoding.UTF8.GetString(data);

    if (text != "")
    {
        // 在這裡把IoT Hub的資料抓出來, text就是從IoT Hub中取得的JSON資料字串
        // text = ......
    }
}

基本上IoTProcessor.cs的程式碼到這邊就已經可以執行了,但是由於有一些屬性是要從外部傳入的,所以接下來會回到Program.cs這個程式主要的進入點,並進行程式碼的設計

9.在Program.cs中,Main()的程式進入點加上下面的程式碼

static void Main()
{
    string iotHubConnectionString = "{IoT Hub連線字串}";
    string iotHubD2cEndpoint = "messages/events";
    string strGroupName = "webjob";
    IoTProcessor.StorageConnectionString = "{儲存體連線字串}";
    IoTProcessor.ServiceBusConnectionString = "{ServiceBus連線字串}";
    IoTProcessor.DatabaseConnectString = "{資料庫連線字串}";
    string strBlobName = "messages-events";

    string eventProcessorHostName = Guid.NewGuid().ToString();
    EventProcessorHost eventProcessorHost = 
        new EventProcessorHost(eventProcessorHostName, iotHubD2cEndpoint, strGroupName, 
        iotHubConnectionString, IoTProcessor.StorageConnectionString, strBlobName);

    eventProcessorHost.RegisterEventProcessorAsync<IoTProcessor>().Wait();
    eventProcessorHost.UnregisterEventProcessorAsync().Wait();
}

在這裡要說明一下
iotHubD2cEnpoint的字串設定為"messages/events",這是固定不能修改的
strGroupName就是在Azure上的[取用者群組]名稱
strBlobName是用來將這個WebJob狀態暫存在儲存體上的容器名稱

儲存體在寫程式前要建立,這個動作在[Azure] Azure IoT整合應用二:建立串流分析工作,接收從IoT Hub的訊息並進行處理文中有提到,可以使用同一個儲存體,建立不同的容器即可

10.在App.config中,connectionStrings裡有兩個連線字串,分別是[AzureWebJobsDashboard][AzureWebJobsStorage],請給予儲存體的連線字串

請一定要加入連線字串,不然程式無法執行

基本上程式碼到這邊,重點部份就算全部講完了,實際執行一下,就可以透過Console.WriteLine的指令,顯示出從IoT Hub取得的訊息內容

11.最後一步,就是將程式發佈至WebApp中,在JobProcessor專案中,點選[Publish as Azure WebJob],並選擇雲端的WebApp後就可以發佈完成了

發佈完的WebJob,有可能會因為太久沒有執行所以發生停止的狀況,所以必須要將WebApp的設定要將設定[一律開啟]變更為[開啟]的設定,WebJob才不會因為久沒執行而停止

請記得打開WebJob所屬的WebApp,[一律開啟]的設定

由於透過程式碼讀取IoT Hub的功能,可以彌補串流分析無法達到的功能,像是太過複雜的運算邏輯,或是輸出不包含在串流分析中原本就提供的功能,WebJob的寫法亦是不可或缺的一種方式
因為透過程式取得IoT資訊的程式量較多, 有興趣的人請一定要看參考資料所附上的網頁連結,並從GitHub上取得完整的程式碼,不然只有文章中所提到的重點程式,是無法完整執行IoT Hub的讀取與運作的

有興趣的人請一定要參考GitHub上的程式,光文章內容的程式是不夠的

程式碼GitHub連結:
https://github.com/madukapai/maduka-Azure-IoT

參考資料:
教學課程:如何處理 IoT 中樞裝置到雲端訊息