物聯網開發筆記 (六) Google Serverless
透過 Google Cloud Serverless 打造一台 iOT 終端設備的中樞,讓它利用 MQTT 協議自動通知所有訂閱的設備。
我的架構上會有一台 Node.js Serverless 伺服器,因為屆時我的 Mobile APP 是不希望直接連 MQTT Broker 的,都透過 Serverless 來協助,順便發推播訊息,但這一台的架設就見仁見智了,不是必備需要的,只要有相同方式可以達成要求都可以。
Server 會有一個 API(理論上是 function,FaaS),這個 API 被呼叫後,會自動透過 MQTT Pub 發送新的設定給終端伺服器,終端伺服器也可以安排時間定時取得新的資料。
Firebase
由於我之後會有其他的功能搭配使用,所以我直接使用 Firebase 來實作,當然也可以直接到 Google Cloud Functions 建立,那邊建立可以選擇 v1 or v2 的版本,目前也支援 Python。
先安裝 Firebase CLI
npm install -g firebase-tools
第一次使用要登入 Google 帳號
firebase login
建立好專案空資料夾後,用 Terminal 到該資料夾下,準備初始化
firebase init

出現上圖後,第一個步驟是要選擇要使用到的功能,這邊就先選擇 Functions,若有需要透過 CLI 工具來操作其他的功能,也可以一併選擇。

這邊有些選項可以選擇,若已有 Firebase 專案了,可以選擇 Use an existing project
來操作既有專案,也可以選 Create a new project
來建立新專案。

這邊會請你選擇撰寫 Cloud Functions 的語言,我這邊選 TypeScript,就看個人喜好。

詢問是否使用 ESLint 風格,這個會嚴格規定程式的撰寫 Style,我這邊選 n

接著詢問你是不是要先安裝相關依賴項,可以選 n 在自己下 npm install
這邊就先選擇 Y


如果當初有選 Functions 其他的功能,這邊還會有其他功能的資料夾。
安裝 mqtt module
cd Functions
npm install mqtt
需要注意的是,要安裝套件給 Functions 內使用,要進入 Functions 資料夾內下 npm install
Serverless 實作
首先定義好 function name,因為連線 mqtt broker 以及取得一些相關的資料需要的時間每次都不一樣,所以我希望這個請求一開始就直接回傳 203
給呼叫端,讓伺服器後續自己完成即可。
import * as functions from "firebase-functions";
export const testFunction = functions.region('asia-east1').https.onRequest(async (req, res) => {
res.status(202).send('Server will process your request.');
});
region 代表指定 Google Cloud 機房位置
匯入 mqtt
const mqtt = require('mqtt');
定義 mqtt broker 連線資訊
const options = {
clientId: 'gcp-server',
username: 'user',
password: 'pass',
clean: true,
};
連線
const client = mqtt.connect('mqtts://broker:port', options);
取得連線結果並送出 Pub
client.on('connect', () => {
if (client.connected === true) {
console.log('MQTT 連線成功');
// 看要在哪個環節實作取得所需相關資料,這邊就可以直接使用
const json = {
key: value
}
const result = JSON.stringify(json);
client.publish(topic, JSON.stringify(result));
console.log(topic + ' 已嘗試發送,body = ' + result);
client.end();
}
});
Deploy 部署
寫好之後,透過 Firebase CLI 到專案資料夾下(整個專案,非 Functions 內),透過以下指令
firebase deploy --only functions:functionName
以上的方式是指定部署某一個 function
若要將所有 function 都部署上去
firebase deploy --only functions

部署成功後,會出現一串網址,這就是你的 function 呼叫網址,也可以到後台去查看。


觸發方式不是只有 HTTP,也可以設定偵測到 storage、資料庫等發生資料變化時自動執行等。
經過實驗,除了 Serverless 冷啟動時需要的時間較長,其餘都還蠻快就收到資訊。
Google Cloud Serverless 也可以搭配 crontab
排程自動執行,以下是在網路上查到的工具,可以方便設定時間格式