本教學課程說明如何使用 WebSockets 建立多聊天室即時通訊服務,並透過永久連線進行雙向通訊。有了 WebSockets,用戶端和伺服器都能互相推送訊息,不必輪詢伺服器來取得更新。
雖然您可以將 Cloud Run 設為使用工作階段相依性,但這項功能會提供盡力而為的相依性,也就是說,任何新要求仍有可能轉送至其他執行個體。因此,聊天服務中的使用者訊息必須在所有執行個體之間同步處理,而不只是在連線至一個執行個體的用戶端之間同步處理。
設計即時通訊服務
這個範例即時通訊服務使用 Memorystore for Redis 執行個體,在所有執行個體中儲存及同步處理使用者訊息。Redis 使用 Pub/Sub 機制 (請勿與 Cloud Pub/Sub 產品混淆),將資料推送至連線至任何執行個體的訂閱用戶端,以消除 HTTP 輪詢更新。
不過,即使採用推送更新,任何啟動的執行個體也只會收到推送至容器的新訊息。如要載入先前的訊息,必須將訊息記錄儲存至永久儲存空間解決方案,並從中擷取。這個範例使用 Redis 的物件儲存庫傳統功能,快取及擷取訊息記錄。
Redis 執行個體使用私人 IP,可防範網際網路中的各種威脅,並控管及限制存取權,僅允許在與 Redis 執行個體相同的虛擬私人網路中執行的服務存取。建議您使用直連虛擬私有雲輸出。
限制
本教學課程不會說明使用者驗證或工作階段快取。如要進一步瞭解使用者驗證,請參閱 Cloud Run 的使用者驗證教學課程。
本教學課程不會實作 Firestore 等資料庫,用於無限期儲存及擷取即時通訊訊息記錄。
這項範例服務需要額外元素,才能用於正式環境。建議使用標準級 Redis 執行個體,透過複製和自動容錯移轉功能提供高可用性。
目標
編寫、建構及部署使用 WebSocket 的 Cloud Run 服務。
連線至 Memorystore for Redis 執行個體,在執行個體之間發布及訂閱新訊息。
使用直接虛擬私有雲輸出,將 Cloud Run 服務與 Memorystore 連結。
費用
在本文件中,您會使用下列 Google Cloud計費元件:
您可以使用 Pricing Calculator,根據預測用量估算費用。
事前準備
- 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
啟用 Cloud Run、Memorystore for Redis、Artifact Registry 和 Cloud Build API (如有尚未啟用的 API)。
啟用 API 所需的角色
您必須具備
serviceusage.services.enable權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「Service Usage 管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。- 安裝並初始化 gcloud CLI。
必要的角色
如要取得完成教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:
- Artifact Registry 讀取者 (
roles/artifactregistry.reader) - Cloud Build 編輯者 (
roles/cloudbuild.builds.editor) - Cloud Memorystore Redis 管理員 (
roles/redis.admin) - Cloud Run 管理員 (
roles/run.admin) - 建立服務帳戶 (
roles/iam.serviceAccountCreator) - 專案 IAM 管理員 (
roles/resourcemanager.projectIamAdmin) - 服務帳戶管理員 (
roles/iam.serviceAccountAdmin) - 服務使用情形消費者 (
roles/serviceusage.serviceUsageConsumer)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
設定 gcloud 預設值
如要針對 Cloud Run 服務設定 gcloud 的預設值:
設定您的預設專案:
gcloud config set project PROJECT_ID
將 PROJECT_ID 替換為您為本教學課程建立的專案名稱。
為所選區域設定 gcloud:
gcloud config set run/region REGION
將 REGION 替換為您選擇的支援 Cloud Run 區域。
Cloud Run 位置
Cloud Run 具有區域性,這表示執行 Cloud Run 服務的基礎架構位於特定區域,並由 Google 負責管理,實現該區域內所有可用區之間的備援可用性。
選擇執行 Cloud Run 服務的區域時,主要考量重點在於延遲時間、可用性或耐用性需求。原則上可以選擇距離使用者最近的區域,但也應考慮 Cloud Run 服務所用其他 Google Cloud產品的位置。如果跨多個位置使用 Google Cloud 產品,可能會影響服務的延遲時間和費用。
Cloud Run 可在下列地區使用:
採用級別 1 定價
asia-east1(臺灣)asia-northeast1(東京)asia-northeast2(大阪)asia-south1(印度孟買)asia-southeast3(曼谷)europe-north1(芬蘭)低二氧化碳排放
europe-north2(斯德哥爾摩)低二氧化碳排放
europe-southwest1(馬德里)低二氧化碳排放
europe-west1(比利時)低二氧化碳
europe-west4(荷蘭)低二氧化碳排放
europe-west8(米蘭)低二氧化碳排放
europe-west9(巴黎)低二氧化碳排放
me-west1(特拉維夫)northamerica-south1(墨西哥)us-central1(愛荷華州)低二氧化碳排放
us-east1(南卡羅來納州)us-east4(北維吉尼亞州)us-east5(哥倫布)us-south1(達拉斯)低二氧化碳排放
us-west1(奧勒岡州)低二氧化碳排放
採用級別 2 定價
africa-south1(約翰尼斯堡)asia-east2(香港)asia-northeast3(韓國首爾)asia-southeast1(新加坡)asia-southeast2(雅加達)asia-south2(印度德里)australia-southeast1(雪梨)australia-southeast2(墨爾本)europe-central2(波蘭華沙)低二氧化碳
europe-west10(柏林)europe-west12(杜林)低二氧化碳排放
europe-west2(英國倫敦)低二氧化碳排放
europe-west3(德國法蘭克福)europe-west6(瑞士蘇黎世)低二氧化碳
me-central1(杜哈)me-central2(達曼)northamerica-northeast1(蒙特婁)低二氧化碳排放
northamerica-northeast2(多倫多)低二氧化碳排放
southamerica-east1(巴西聖保羅)低二氧化碳排放
southamerica-west1(智利聖地牙哥)低二氧化碳排放
us-west2(洛杉磯)us-west3(鹽湖城)us-west4(拉斯維加斯)
如果您已建立 Cloud Run 服務,可以在Google Cloud 控制台的 Cloud Run 資訊主頁中查看區域。
擷取程式碼範例
如要擷取要使用的程式碼範例:
將範例存放區複製到本機電腦中:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
您也可以 下載範例 ZIP 檔案,然後解壓縮。
變更為包含 Cloud Run 程式碼範例的目錄:
Node.js
cd nodejs-docs-samples/run/websockets/
瞭解 WebSocket 程式碼
Socket.io 程式庫可在瀏覽器和伺服器之間,建立即時雙向通訊。雖然 Socket.io 不是 WebSocket 實作,但它確實包裝了功能,為多個通訊協定提供更簡單的 API,並提供額外的功能,例如提高可靠性、自動重新連線,以及向所有或部分用戶端廣播。
用戶端整合
用戶端會為每個連線例項化新的通訊端例項。由於這個範例是在伺服器端算繪,因此不需要定義伺服器網址。Socket 執行個體可以發出及監聽事件。
伺服器端整合
在伺服器端,Socket.io 伺服器會初始化並附加至 HTTP 伺服器。與用戶端類似,Socket.io 伺服器與用戶端建立連線後,系統會為每個連線建立通訊端執行個體,可用於發出及監聽訊息。Socket.io 也提供介面,可建立「聊天室」或任意管道,讓 Socket 加入及離開。
Socket.io 也提供 Redis 轉接器,無論是哪個伺服器提供通訊端,都能將事件播送至所有用戶端。Socket.io 只會使用 Redis 的 Pub/Sub 機制,不會儲存任何資料。
Socket.io 的 Redis 轉接器可重複使用 Redis 用戶端,用於儲存聊天室的訊息記錄。每個容器都會建立與 Redis 執行個體的連線,而 Cloud Run 可以建立大量執行個體。這遠低於 Redis 可支援的 65,000 個連線。
重新連線
Cloud Run 的逾時時間上限為 60 分鐘。因此,您需要新增重新連線邏輯,以因應可能發生的逾時情況。在某些情況下,Socket.io 會在中斷連線或連線錯誤事件後,自動嘗試重新連線。我們無法保證用戶端會重新連線至同一個執行個體。
如果連線處於有效狀態,執行個體會持續存在,直到所有要求關閉或逾時為止。即使您使用 Cloud Run 工作階段相依性,新要求仍可能透過負載平衡機制分配至運作中的容器,讓容器縮減資源。如果擔心流量激增後仍有大量容器持續存在,可以降低逾時值上限,更頻繁地清除未使用的通訊端。
推出服務
建立 Memorystore for Redis 執行個體:
gcloud redis instances create INSTANCE_ID --size=1 --region=REGION
更改下列內容:
- INSTANCE_ID:執行個體的名稱,例如
my-redis-instance。 - REGION_ID:所有資源和服務的區域,例如
europe-west1。
系統會自動從預設服務網路範圍,為執行個體分配 IP 範圍。本教學課程使用 1 GB 的記憶體,在本機快取 Redis 執行個體中的訊息。進一步瞭解如何根據用途決定 Memorystore 執行個體的初始大小。
- INSTANCE_ID:執行個體的名稱,例如
使用 Redis 執行個體授權網路的 IP 位址,定義環境變數:
export REDISHOST=$(gcloud redis instances describe INSTANCE_ID --region REGION --format "value(host)")
建立服務帳戶,做為服務身分。根據預設,除了專案成員資格外,這項服務沒有其他權限。
gcloud iam service-accounts create chat-identity gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:chat-identity@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/serviceusage.serviceUsageConsumer
執行下列指令,找出 Redis 執行個體授權的虛擬私有雲網路名稱:
gcloud redis instances describe INSTANCE_ID --region REGION --format "value(authorizedNetwork)"
更改下列內容:
- INSTANCE_ID:執行個體的名稱,例如
my-redis-instance。 - REGION_ID:所有資源和服務的區域,例如
europe-west1。
記下虛擬私有雲網路名稱。
- INSTANCE_ID:執行個體的名稱,例如
建構容器映像檔並部署至 Cloud Run:
gcloud run deploy chat-app --source . \ --allow-unauthenticated \ --timeout 3600 \ --service-account chat-identity \ --network NETWORK \ --subnet SUBNET \ --update-env-vars REDISHOST=$REDISHOST
更改下列內容:
- NETWORK 是 Redis 執行個體附加的授權虛擬私有雲網路名稱。
- SUBNET 是子網路名稱。子網路不得小於
/26。直連虛擬私有雲輸出支援 IPv4 範圍 RFC 1918、RFC 6598 和 E 類。
如果系統提示您安裝必要 API,請回覆
y。每個專案只需執行一次這項操作。如果您尚未按照設定頁面所述設定預設值,請提供平台和區域,回應其他提示。進一步瞭解如何從原始碼部署。
試用服務
如要試用完整服務,請按照下列步驟操作:
在瀏覽器中前往部署步驟提供的網址。
新增名稱和聊天室即可登入。
傳送訊息到聊天室!
如果您選擇繼續開發這些服務,請注意,這些服務對 Google Cloud 其餘部分的 Identity and Access Management (IAM) 存取權有限,必須授予其他 IAM 角色,才能存取許多其他服務。
清除所用資源
為避免系統向您的 Google Cloud 帳戶收取額外費用,請刪除您在本教學課程中部署的所有資源。
刪除專案
如果您是為了這個教學課程建立新專案,請刪除專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源。
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。
刪除專案的方法如下:
- 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。
- 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。
刪除教學課程資源
刪除您在本教學課程中部署的 Cloud Run 服務。Cloud Run 服務在收到要求前不會產生費用。
如要刪除 Cloud Run 服務,請執行下列指令:
gcloud run services delete SERVICE-NAME
將 SERVICE-NAME 改為您的服務名稱。
您也可以從Google Cloud 控制台刪除 Cloud Run 服務。
移除您在教學課程設定期間新增的
gcloud預設區域設定:gcloud config unset run/region移除專案設定:
gcloud config unset project刪除在本教學課程中建立的其他 Google Cloud 資源:
- 從 Artifact Registry 刪除服務容器映像檔
gcr.io/PROJECT_ID/chat-app - 刪除服務帳戶
chat-identity@PROJECT_ID.iam.gserviceaccount.com - 刪除 Memorystore for Redis 執行個體
- 從 Artifact Registry 刪除服務容器映像檔
後續步驟
進一步瞭解 Socket.io 的運作方式和進階用法。
深入瞭解透過虛擬私有雲網路直連虛擬私有雲輸出。
請參閱 Memorystore 和在 Cloud Run 使用 WebSocket 的最佳做法。