, ,

物聯網開發筆記 (六) Google Serverless

透過 Google Cloud Serverless 打造一台 iOT 終端設備的中樞,讓它利用 MQTT 協議自動通知所有訂閱的設備。

物聯網開發筆記 (六) Google Serverless
Photo by Taylor Vick / Unsplash

我的架構上會有一台 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
安裝 CLI 方便使用

第一次使用要登入 Google 帳號

firebase login
登入 Google 帳號,就會抓到該帳號下的專案

建立好專案空資料夾後,用 Terminal 到該資料夾下,準備初始化

firebase init
幫專案資料夾初始化
初始化操作畫面

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

選擇專案或建立

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

選擇使用語言

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

是否使用 ESLint

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

是否安裝依賴

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

Done
資料夾畫面

如果當初有選 Functions 其他的功能,這邊還會有其他功能的資料夾。

安裝 mqtt module

GitHub - mqttjs/MQTT.js: The MQTT client for Node.js and the browser
The MQTT client for Node.js and the browser. Contribute to mqttjs/MQTT.js development by creating an account on GitHub.
cd Functions
npm install mqtt
安裝 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.');
});
一開始直接回傳 202

region 代表指定 Google Cloud 機房位置

匯入 mqtt

const mqtt = require('mqtt');
使用 mqtt module

定義 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();
    }
});
送出 pub 並關閉連線

Deploy 部署

寫好之後,透過 Firebase CLI 到專案資料夾下(整個專案,非 Functions 內),透過以下指令

firebase deploy --only functions:functionName
部署指定 function

以上的方式是指定部署某一個 function

若要將所有 function 都部署上去

firebase deploy --only functions
部署全部 function
部署成功畫面

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

觸發方式不是只有 HTTP,也可以設定偵測到 storage、資料庫等發生資料變化時自動執行等。


經過實驗,除了 Serverless 冷啟動時需要的時間較長,其餘都還蠻快就收到資訊。

Google Cloud Serverless 也可以搭配 crontab 排程自動執行,以下是在網路上查到的工具,可以方便設定時間格式

Crontab.guru - The cron schedule expression editor
An easy to use editor for crontab schedules.