landing_image landing_image landing_image landing_image landing_image landing_image landing_image
portrait

YX.S

成為一個厲害的普通人

公司有個需求是要可以遠端遙控門鎖開門

原本公司的開門服務是在Azure上開台VM

並且在上面架設mqtt這個協議作為訊息傳遞的媒介

但主管認為這個方式太浪費了,然後發現GCP上有類似的服務

因此就來研究看看了…

 

GCP Pub/Sub

這是一款Google所推出的雲端服務

主要在解決企業應用程式、機器之間訊息傳遞的問題

官網是這樣寫的:

Cloud Pub/Sub brings the scalability, flexibility, and reliability of enterprise message-oriented middleware to the cloud.

By providing many-to-many, asynchronous messaging that decouples senders and receivers, it allows for secure and

highly available communication between independently written applications. Cloud Pub/Sub delivers low-latency, durable

messaging that helps developers quickly integrate systems hosted on the Google Cloud Platform and externally.

弱弱的翻譯就是:

Cloud Pub/Sub 是可擴展、彈性以及可以信任的一款企業訊息傳遞導向的中介層。

提供了多對多、非同步的訊息使接收端與發送端可分離,它使獨立的應用程式能夠安全且多次溝通。Cloud Pub/Sub的低延遲以及持久性

以幫助開發者們在Google Cloud Platform上快速的整合系統

Pub/Sub 基本

  • Message:從裝置中送出的資料
  • Topic:一個在GCP Pub/Sub中建好,用來接收資料的實體
  • Subscription:一個在GCP Pub/Sub中建好,用來訂閱特定的Topic的實體,使得可以接收訊息
  • Publisher:用來發出Message到特定Topic
  • Subscriber:從特定的Subscription收到訊息

圖的大意就是:

Topic 以及 Subscription 是我們要先在GCP上建立好

  1. Publisher 送出 Message 到 Topic
  2. Topic 先儲存 Message
  3. Subscription 收到 Topic 傳來的 Message
  4. 將訊息傳給 Subscriber
  5. Subscriber 收到 Message,發出一個確認(acknowledged),Topic就會將訊息刪除

 

實作

進到 GCP PUB/SUB 頁面,點選 VIEW DOCUMENTATION


點選左邊的 Using Client Libraries
這裡的解說蠻清楚的,讓我們依照文件的指示來操作


PUBLISH端

1.選擇專案

點下去 Set up a GCP Console project

選擇你要新增的專案,並按下NEXT

他會產生一個 SERVICE ACCOUNT 檔案給你下載

這裡面會存放一些用來跟google API溝通的資料

產生的 SERVICE ACCOUNT 我們可以在控制台中看到

 

2.設定環境變數

前一步驟下載的資料可以讓 google 認證我們

但還是要設個變數,讓我們有辦法跟 google 溝通

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

 

3.安專相關套件

這邊有點奇怪,文件上面是寫

composer require google/apiclient

但經過測試過後發現是要安裝下列這個才不會出錯

composer require google/cloud-pubsub

 

4.實際測試

做完以上的步驟,應該就可以發送訊息了!

 

PUBLISHER端

實際測試(PHP):

 

use Google\Cloud\PubSub\PubSubClient;

 

function publish_message()

{

    $pubsub = new PubSubClient([

        'projectId' => [YOUR_PROJECT_ID],

    ]);

 

    $topic = $pubsub->topic([YOUR_TOPIC_NAME]);

    $topic->publish(['data' => 'YOUR_MESSAGE']);

 

    return response()->json([

        'status' => 'success',

        'message' => 'send data success'

    ]);

}

SUBSCRIPTION端

重複上述1,2步驟

1.安裝套件

因為是要在樹莓派上操作,而樹莓派已經內建 python2.7

所以我們就安裝 python 的套件

pip install --upgrade google-cloud-pubsub

 

2.自動執行

因為在樹莓派上操作,不確定樹莓派是否會有重開機的可能

因此要設定開機自動執行程式

sudo nano ~/.config/lxsession/LXDE-pi/autostart

在裡面編輯寫上程式的所在位置

@/usr/bin/python [YOUR_PROGRAM_LOCATION]

3.實際測試

import time

from google.cloud import pubsub

project = [YOUR_PROJECT_ID]

subscription_name = [YOUR_SUBSCRIPTION_NAME]

subscriber = pubsub.SubscriberClient()

subscription_path = subscriber.subscription_path(

project, subscription_name)

 

def callback(message):

    print('Received message: {}'.format(message))

    # 在這邊在乎叫真正開門的Python程式

    message.ack()

 

subscriber.subscribe(subscription_path, callback=callback)

# The subscriber is non-blocking, so we must keep the main thread from

# exiting to allow it to process messages in the background.

print('Listening for messages on {}'.format(subscription_path))

while True:

    time.sleep(60)