在前一篇文章[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套件
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狀態暫存在儲存體上的容器名稱
10.在App.config中,connectionStrings裡有兩個連線字串,分別是[AzureWebJobsDashboard]與[AzureWebJobsStorage],請給予儲存體的連線字串
基本上程式碼到這邊,重點部份就算全部講完了,實際執行一下,就可以透過Console.WriteLine的指令,顯示出從IoT Hub取得的訊息內容
11.最後一步,就是將程式發佈至WebApp中,在JobProcessor專案中,點選[Publish as Azure WebJob],並選擇雲端的WebApp後就可以發佈完成了
發佈完的WebJob,有可能會因為太久沒有執行所以發生停止的狀況,所以必須要將WebApp的設定要將設定[一律開啟]變更為[開啟]的設定,WebJob才不會因為久沒執行而停止
由於透過程式碼讀取IoT Hub的功能,可以彌補串流分析無法達到的功能,像是太過複雜的運算邏輯,或是輸出不包含在串流分析中原本就提供的功能,WebJob的寫法亦是不可或缺的一種方式
因為透過程式取得IoT資訊的程式量較多, 有興趣的人請一定要看參考資料所附上的網頁連結,並從GitHub上取得完整的程式碼,不然只有文章中所提到的重點程式,是無法完整執行IoT Hub的讀取與運作的
程式碼GitHub連結:
https://github.com/madukapai/maduka-Azure-IoT
參考資料:
教學課程:如何處理 IoT 中樞裝置到雲端訊息