

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon GameLift Streams 後端服務和 Web 用戶端
<a name="sdk"></a>

 Amazon GameLift Streams 可讓您透過 Web 瀏覽器串流應用程式。透過 Amazon GameLift Streams Web SDK，您可以設定後端串流服務。然後，最終使用者會透過 Web 用戶端連線至串流。他們可以透過雲端播放遊戲或與應用程式互動。

 Amazon GameLift Streams Web SDK 包含範例後端伺服器和範例 Web 用戶端，可用來開始建立後端服務。您也可以使用這些範例來測試 Amazon GameLift Streams 串流的方式，而無需額外開發。若要開始使用，請參閱 [使用 Amazon GameLift Streams 設定 Web 伺服器和用戶端](setting-up-web-sdk.md)。

**Topics**
+ [支援的瀏覽器和輸入](sdk-browsers-input.md)
+ [必要的連接埠](required-ports.md)
+ [使用 Amazon GameLift Streams 設定 Web 伺服器和用戶端](setting-up-web-sdk.md)
+ [自訂串流外觀](sdk-stream-appearance.md)
+ [地區設定偏好設定](sdk-locale-support.md)
+ [滑鼠移動處理](sdk-mouse-movement.md)
+ [應用程式與 Web 用戶端之間的資料通道通訊](data-channels.md)

# 支援的瀏覽器和輸入
<a name="sdk-browsers-input"></a>

以下列出支援用於檢視 Amazon GameLift Streams 串流及其相容輸入周邊的平台和瀏覽器。瀏覽器也必須與進階影片編碼 (AVC) 相容，也稱為 H.264。

整體而言，我們建議使用 Google Chrome、Microsoft Edge 或自訂 Chromium 桌面應用程式，以獲得最佳的最終使用者體驗和最大的相容性，特別是遊戲控制器。

 若要進一步了解哪些控制器與哪些瀏覽器相容，請參閱 [Web Gamepad API](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API)。雖然有些指引可能不適用於 Amazon GameLift Streams，但我們預期大多數遊戲控制器都能透過藍牙成功連線。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/gameliftstreams/latest/developerguide/sdk-browsers-input.html)

## 已知問題
<a name="sdk-browsers-input-known-issues"></a>

以下是瀏覽器和輸入的已知問題：
+ 只要按下 ，Safari `Esc` 就會立即退出全螢幕。這無法覆寫。
+ iOS 不支援諸如 LinkedIn、Yelp、Instagram 等行動應用程式內的「內嵌」或「應用程式內」瀏覽器檢視。這些往往會停用即時互動式串流所需的瀏覽器 WebRTC 支援。我們建議偵測非標準瀏覽器字串，並提示使用者在 Safari 中開啟。
+ 如果應用程式中的螢幕解析度未設定為 1080p，則滑鼠追蹤可能會受到影響。如果可能，我們建議您停用任何其他解析度的選擇。我們也建議停用視窗化模式，並且只在全螢幕中執行。
+ 為了在 Proton 上支援遊戲控制器的隨插即用，即使原生 Linux 應用程式中不支援這些控制器，在 Proton 執行時間環境中執行的遊戲*仍會*顯示遊戲控制器已連線，即使用戶端上沒有插入。這可能是在控制器閒置且未使用時提示控制器輸入的遊戲問題。我們建議遊戲根據最後一個輸入方法顯示輸入 UI。

## 限制
<a name="sdk-browsers-input-limits"></a>
+ 大多數執行時間環境都支援遊戲控制器，但 Ubuntu 22.04 LTS 除外。如果您需要遊戲控制器支援，請考慮使用另一個執行時間環境來建立遊戲。如需其他執行時間環境的清單，請參閱 [執行期環境](configuration-options.md#configuration-options-runtime)。
+ Firefox 不支援 PlayStation 5 和 Luna 遊戲控制器。
+ 觸覺回饋支援：
  + Chrome、Edge 和 Safari 支援 PlayStation 4 和 Xbox Series S/X 控制器的觸覺回饋。
  + PlayStation 5 DualSense 控制器上的觸覺僅支援 Safari 瀏覽器。
  + Firefox 不支援任何控制器的觸覺回饋。
  + Android 和 iOS 裝置不支援任何控制器的觸覺回饋。
+ Amazon GameLift Streams 主控台中的**測試串流**功能不支援麥克風。

## IPv6 支援
<a name="sdk-browsers-input-ipv6-support"></a>

只有 Windows 執行時間應用程式才支援串流至IPv6-only 的用戶端。


| 執行時期 | 透過 IPv4 串流 | 透過 IPv6 串流 | 
| --- | --- | --- | 
| Microsoft Windows Server 2022 Base | 是 | 是 | 
| Ubuntu 22.04 LTS | 是 | 否 | 
| Proton 執行時間 | 是 | 否 | 

# 必要的連接埠
<a name="required-ports"></a>

 若要整合 Amazon GameLift Streams，請確定您的網路基礎設施已開啟並可存取必要的連接埠。以下是您應該計劃在網路上開啟以與 Amazon GameLift Streams 通訊的連接埠清單。


| 連接埠 | 通訊協定 | 用途 | 
| --- | --- | --- | 
|  443  |  (HTTPS) TCP  |  AWS APIs，包括 Amazon GameLift Streams  | 
|  33435-33465  |  UDP  |  Web RTC  | 

# 使用 Amazon GameLift Streams 設定 Web 伺服器和用戶端
<a name="setting-up-web-sdk"></a>

 在本教學課程中，您將設定整合 Amazon GameLift Streams 串流服務的 Web 用戶端應用程式。然後，您將使用 Amazon GameLift Streams Web SDK、JavaScript 程式庫和您可以開始的範例程式碼。範例程式碼包含簡單的 Amazon GameLift Streams 後端 Web 伺服器和簡單的 Web 用戶端。在本教學課程結束時，您可以使用範例程式碼啟動串流。

 如果您是第一次使用 Amazon GameLift Streams，強烈建議您從教學課程開始，該[在 Amazon GameLift Streams 中啟動您的第一個串流](streaming-process.md)教學課程會逐步引導您將遊戲上傳到 Amazon S3，並在瀏覽器的 Amazon GameLift Streams 主控台中測試串流。

## 先決條件
<a name="setting-up-web-sdk-prereq"></a>
+ 具有適當登入資料以進行程式設計存取的 AWS 帳戶。如需詳細資訊，請參閱[將 Amazon GameLift Streams 設定為開發人員](setting-up.md)。
+ AWS 開發套件。
+ Amazon GameLift Streams 支援的 Web 瀏覽器 — 請參閱 [支援的瀏覽器和輸入](sdk-browsers-input.md)。
+ Node.js — 請參閱 [Node.js 下載](https://nodejs.org/en/download)頁面。

## 下載 Web 開發套件
<a name="setting-up-web-sdk-materials"></a>

在本教學課程中，您將需要從[入門產品頁面](https://aws.amazon.com/gamelift/streams/getting-started/)的資源區段下載下列資料：
+ **Amazon GameLift Streams Web SDK 套件**：這包含簡單後端服務和 Web 用戶端的範例程式碼。
+ **Amazon GameLift Streams Web SDK API 參考**：此 API 參考會記錄適用於 JavaScript 的 Amazon GameLift Streams API 包裝函式。

## 設定串流資源
<a name="setting-up-web-sdk-resources"></a>

您必須擁有串流資源，即應用程式和串流群組，才能啟動串流。具體而言，您必須擁有：
+  處於**就緒**狀態的應用程式。
+  處於**作用中**狀態且具有可用串流容量的串流群組。
+  對於在主要位置以外的位置進行串流，應用程式必須已完成複寫到該位置。

 若要使用 Amazon GameLift Streams 主控台或 Amazon GameLift Streams CLI 設定應用程式和串流群組[使用 Amazon GameLift Streams 串流群組管理串流](stream-groups.md)，請分別參閱 [在 Amazon GameLift Streams 中準備應用程式](applications.md)和 。或者，如需 end-to-end演練，請參閱 [在 Amazon GameLift Streams 中啟動您的第一個串流](streaming-process.md)。 GameLift 

## 設定後端伺服器
<a name="setting-up-web-sdk-backend"></a>

 後端伺服器負責處理任務，例如驗證使用者、設定串流參數，以及代表最終使用者執行 Amazon GameLift Streams 服務 API 呼叫。檢閱範例程式碼和 Amazon GameLift Streams Web SDK API 參考，以進一步了解如何設定。具體而言，請參閱 Amazon GameLift Streams Web SDK 套件中的 server.js 檔案。

**重要**  
 此程式碼是僅供測試和評估之用的範例程式碼，不應用於生產容量。

**執行範例後端服務**

1.  開啟終端機或命令提示字元，然後導覽至資料夾 `AmazonGameLiftStreamsWebSDK\GameLiftStreamsSampleGamePublisherService\`。

1.  執行下列命令：

   ```
   npm install
   node server.js
   ```

 執行範例後端服務後，最終使用者可以透過 Web 用戶端連線至串流。在下一個步驟中測試 Web 用戶端。

## 啟動 Web 用戶端
<a name="setting-up-web-sdk-client"></a>

Web 用戶端應用程式負責接收和解碼 Amazon GameLift Streams 串流、串流至最終使用者，並提供 Web 瀏覽器 UI 供最終使用者與應用程式互動。檢閱範例程式碼和 Amazon GameLift Streams Web SDK API 參考，以進一步了解如何將 JavaScript Amazon GameLift Streams Web SDK 整合到您自己的 Web 用戶端應用程式。具體而言，請參閱 Amazon GameLift Streams Web SDK 套件`public/index.html`中的 。您也可以在瀏覽器中啟動 Web 用戶端時查看網頁來源。

**注意**  
Amazon GameLift Streams 中的 Windows 執行期支援透過 IPv4 或 IPv6 的串流工作階段。不過，Linux 和 Proton 執行期環境僅支援透過 IPv4 串流。

**啟動 Web 用戶端應用程式**

1.  開啟 Web 瀏覽器並導覽至 `http://localhost:port/`。連接埠號碼由後端伺服器設定；預設情況下，這是 HTTP 連接埠 8000。

1. 玩遊戲或使用軟體。

   1. 若要連接輸入，例如滑鼠，請選擇**連接輸入**。

   1. 若要結束遊戲，請選擇 **Esc** 金鑰。

   1. 若要停止伺服器程序，請選擇 **Ctrl\$1C** 金鑰。

## 清除串流資源
<a name="setting-up-web-sdk-cleanup"></a>

**警告**  
 串流群組在配置串流容量時會產生成本，即使該容量未使用。為了避免不必要的成本，請將串流群組擴展為所需的大小。在開發期間，我們建議您在不使用時，將串流群組中的永遠開啟容量和目標閒置容量擴展到零。如需詳細資訊，請參閱 [將串流群組擴展至零容量](pricing.md#pricing-pause-stream-groups)。

完成教學課程且不再需要串流應用程式後，請依照下列步驟清除 Amazon GameLift Streams 資源。

**刪除串流群組**

 當您刪除串流群組時，Amazon GameLift Streams 會釋放所有串流容量。

**使用 Amazon GameLift Streams 主控台刪除串流群組**

1.  登入 AWS 管理主控台 並開啟 [Amazon GameLift Streams 主控台](https://console.aws.amazon.com/gameliftstreams/)。

1.  若要檢視現有串流群組的清單，請在導覽窗格中選擇**串流群組**。

1.  選擇您要刪除的串流群組名稱。

1.  在串流群組詳細資訊頁面上，選擇**刪除**。

1.  在**刪除**對話方塊中，確認刪除動作。

 Amazon GameLift Streams 會開始釋出運算資源並刪除串流群組。在此期間，串流群組處於**刪除**狀態。Amazon GameLift Streams 刪除串流群組之後，您就無法再擷取它。

**刪除應用程式**

 您只能刪除符合下列條件的應用程式：
+  應用程式處於**就緒**或**錯誤**狀態。
+  應用程式未在任何進行中串流工作階段內串流。您必須等到用戶端結束串流工作階段，或在 Amazon GameLift Streams API 中呼叫 [TerminateStreamSession](https://docs.aws.amazon.com/gameliftstreams/latest/apireference/API_TerminateStreamSession.html) 來結束串流。

 如果應用程式已連結至任何串流群組，您必須先將其與所有關聯串流群組中解除連結，才能刪除該應用程式。在主控制台上，在對話方塊引導下完成此流程。

**使用 Amazon GameLift Streams 主控台刪除應用程式**

1. 登入 AWS 管理主控台 並開啟 [Amazon GameLift Streams 主控台](https://console.aws.amazon.com/gameliftstreams/)。

1. 在導覽列中，選擇**應用程式**以檢視現有應用程式的清單。選擇您要刪除的應用程式。

1. 在應用程式詳細資訊頁面中，選擇**刪除**。

1. 在**刪除**對話方塊中，確認刪除動作。

 Amazon GameLift Streams 會開始刪除應用程式。在此期間，應用程式處於 `Deleting` 狀態。Amazon GameLift Streams 刪除應用程式後，您就無法再擷取它。

# 自訂串流外觀
<a name="sdk-stream-appearance"></a>

## 載入畫面
<a name="sdk-loading-screen"></a>

當客戶開啟 Web 瀏覽器以檢視串流時，Web 用戶端會開始建立與 Amazon GameLift Streams 串流工作階段的連線。載入串流工作階段時，您可以在客戶的螢幕上顯示自訂背景和標誌。

Amazon GameLift Streams Web SDK 範例用戶端在 `GameLiftStreamsSampleGamePublisherService/public/LoadingScreen/loadingscreen.js` 檔案中示範如何在前端 Web 用戶端中實作動畫標誌。預設載入畫面包含 2 個影像：背景和前景。前景影像位於中間，並具有脈衝動畫。動畫只會在串流工作階段連線時播放。

**啟用載入畫面**

1. 在 Amazon GameLift Streams Web SDK 範例用戶端中，導覽至 `GameLiftStreamsSampleGamePublisherService/public/LoadingScreen/` 資料夾。

1. 使用預設名稱 和 新增背景和前景影像`Background.png``LoadingLogo.png`。如果您想要重新命名它們或使用不同的映像格式，則必須更新 中的程式碼`GameLiftStreamsSampleGamePublisherService/public/loadingscreen.js`。

1. （選用） 在 中`GameLiftStreamsSampleGamePublisherService/public/loadingscreen.js`，更新 JavaScript 程式碼以實作不同的動畫。

# 地區設定偏好設定
<a name="sdk-locale-support"></a>

 在 Amazon GameLift Streams 中，您可以設定每個串流的地區設定偏好設定。如果您的應用程式從最終使用者的作業系統擷取特定位置的資訊，例如時間或貨幣，這會很有用。

 Amazon GameLift Streams 支援下列語言：


| Value | Description | 
| --- | --- | 
|  `en_US`  |  美式英文 （預設）  | 
|  `ja_jp.UTF-8`  |  日文  | 

 **變更地區設定** 

 當您使用 Amazon GameLift Streams API 呼叫 [StartStreamSession](https://docs.aws.amazon.com/gameliftstreams/latest/apireference/API_StartStreamSession.html) 時，請將 `LANG=<language>`新增至您的 `AdditionalEnvironmentVariables`。由於每個使用者的地區設定偏好設定是唯一的，因此您可以在串流工作階段層級設定。如果您未設定此項目，串流預設會使用美式英文。

**Example 範例**  

```
aws gameliftstreams start-stream-session \
   --identifier arn:aws:gameliftstreams:us-west-2:123456789012:streamgroup/1AB2C3De4 \
   --protocol WebRTC \
   --signal-request "[webrtc-ice-offer json string]" \
   --user-id xnshijwh \            
   --additional-environment-variables '{"LANG": "ja_JP.UTF-8"}'
```

# 滑鼠移動處理
<a name="sdk-mouse-movement"></a>

滑鼠移動處理對於在串流應用程式中提供反應靈敏且直覺式的使用者體驗至關重要。Amazon GameLift Streams 會根據您應用程式的游標行為自動最佳化滑鼠輸入傳輸，確保無論游標隱藏或可見，滑鼠移動都會感覺自然。了解 Amazon GameLift Streams 如何處理滑鼠事件，可協助您設計與串流服務無縫搭配的應用程式，並提供最佳的使用者體驗。

## 滑鼠輸入模式
<a name="sdk-mouse-input-modes"></a>

Amazon GameLift Streams 使用兩種不同的模式將滑鼠事件傳輸到您的應用程式，並根據游標可見性自動選取適當的模式：

相對模式  
在相對模式中，滑鼠更新會以與上一個位置的小型增量差異傳輸。此模式非常適合需要精確、持續滑鼠移動追蹤的應用程式，例如第一人稱射擊遊戲 (FPS) 或使用 3D 方向的界面。當作業系統游標隱藏或完全透明時，Amazon GameLift Streams 會使用相對模式。

絕對模式  
在絕對模式中，滑鼠游標位置會以確切的畫面座標傳輸。此模式非常適合依賴精確游標定位的應用程式，例如point-and-click或任何具有可點選元素的 UI。Amazon GameLift Streams 會在作業系統游標可見時使用絕對模式，即使您的應用程式顯示自訂游標影像。

此自動選擇可確保不同應用程式類型的最佳效能，而不需要手動設定。

## 指標鎖定
<a name="sdk-pointer-lock"></a>

指標鎖定是一種 Web API 功能，可擷取特定元素內的滑鼠游標，隱藏游標並防止游標離開指定區域。此功能對於需要不受限制的滑鼠移動以進行相機控制或瞄準的遊戲特別有用，而不會分散可見游標的注意力或到達視窗邊緣的限制。

Amazon GameLift Streams 透過 Web SDK `InputConfiguration`界面中的 `autoPointerLock` 屬性提供自動指標鎖定功能。此功能與 [requestPointerLock API](https://developer.mozilla.org/en-US/docs/Web/API/Element/requestPointerLock) 整合，以提供直覺式且內容感知的滑鼠擷取。

### 自動指標鎖定行為
<a name="sdk-pointer-lock-behavior"></a>

當應用程式為全螢幕且串流主機上看不到遠端游標時，Amazon GameLift Streams 會自動啟用指標鎖定。此行為符合常見的遊戲開發模式：
+ **FPS/TPS 遊戲和 3D 方向控制** - 指標會自動鎖定且游標隱藏，提供 FPS 遊戲所需的無限制攝影機控制。
+ **Point-and-click遊戲和 UI 控制** - 當遊戲讓游標在選單互動或策略遊戲中可見時，指標會保持可見和解鎖狀態，保留預期的使用者體驗。

### 組態選項
<a name="sdk-pointer-lock-configuration"></a>

`autoPointerLock` 屬性接受下列值：

`true`  
當遠端游標隱藏時，一律會擷取滑鼠。

`false`  
無論游標可見性為何，都不會擷取滑鼠。

`'fullscreen'` (default)  
只有在視訊元素處於全螢幕模式且遠端游標不可見時，才會擷取滑鼠。

**重要**  
`autoPointerLock` 由於平台限制，在 Safari 瀏覽器或 iOS 平台上沒有作用。

## 最佳實務
<a name="sdk-mouse-best-practices"></a>

若要確保串流應用程式中的最佳滑鼠處理：
+ **一律串流全螢幕** - 您的應用程式應該已在全螢幕模式下執行，才能在我們的服務上正常運作。此外，我們建議您使用瀏覽器支援，讓串流成為全螢幕元素，以獲得最佳最終使用者體驗。這有助於避免系統游標和軟體游標之間的對齊問題。
+ **隱藏相對動作的游標** - 如果您的應用程式需要相對滑鼠動作 （例如 FPS 樣式的攝影機控制項或以拖曳為基礎的互動），請在這些互動期間隱藏作業系統游標。在某些情況下，您可能需要在滑鼠向下隱藏游標，並在滑鼠向上再次顯示。
+ **顯示絕對定位的游標** - 當您的應用程式需要精確的游標定位以進行 UI 互動時，請確保作業系統游標保持可見，以啟用絕對座標模式。
+ **測試不同的輸入案例** - 確認您的應用程式正確處理相對和絕對滑鼠模式，因為 Amazon GameLift Streams 可能會根據您的游標可見性變更在模式之間切換。
+ **測試不同的視窗模式** - 如適用，在視窗化和全螢幕模式中測試應用程式的滑鼠處理方式。判斷哪個`autoPointerLock`設定最適合您的輸入組態。

# 應用程式與 Web 用戶端之間的資料通道通訊
<a name="data-channels"></a>

 資料通道可讓您在 Amazon GameLift Streams 應用程式與 Web 用戶端 （在最終使用者的 Web 瀏覽器中執行的 JavaScript 程式碼） 之間安全地通訊任意訊息。這可讓最終使用者透過檢視串流的 Web 瀏覽器，與 Amazon GameLift Streams 串流的應用程式互動。

以下是 Amazon GameLift Streams 中資料通道的一些範例使用案例：
+ 使用者可以在本機瀏覽器中開啟應用程式中URLs。
+ 使用者可以將剪貼簿中的內容來回傳遞給應用程式。
+ 使用者可以將內容從本機電腦上傳至應用程式。
+ 開發人員可以在將命令傳送至應用程式的瀏覽器中實作 UI。
+ 使用者可以傳遞結構描述來控制視覺化層的顯示。

## 功能
<a name="data-channels-features"></a>

**訊息大小限制**  
Amazon GameLift Streams Web SDK 對每則訊息施加最大 64 KB (65536 位元組） 的大小限制。這可確保訊息大小限制與大多數瀏覽器相容，而且通訊對串流的總頻寬影響很小。

**指標**  
 串流工作階段結束時，資料管道用量的指標會傳送至您的 AWS 帳戶。如需詳細資訊，請參閱*監控 Amazon GameLift 串流*一節[資料通道](monitoring-cloudwatch.md#monitoring-data-channels)中的 。

## 使用資料通道
<a name="data-channels-using"></a>

Amazon GameLift Streams Web SDK 提供 `sendApplicationMessage`函數，可將訊息作為位元組陣列傳送至應用程式。訊息是由`clientConnection.applicationMessage`您定義的回呼函數處理。

如果用戶端在應用程式連線到資料通道連接埠之前傳送訊息，則會將訊息排入佇列。然後，當應用程式連線時，它會接收訊息。不過，如果應用程式在用戶端連線到資料通道連接埠之前傳送訊息，則訊息會遺失。應用程式必須先檢查用戶端的連線狀態，再傳送訊息。

## 在用戶端
<a name="data-channels-using-client"></a>

在 Web 用戶端應用程式中撰寫下列程式碼。

1.  定義回呼函數以接收來自應用程式的傳入訊息。

   ```
   function streamApplicationMessageCallback(message) {
       console.log('Received ' + message.length + ' bytes of message from 
       Application');
   }
   ```

1.  `clientConnection.applicationMessage` 設定為您的回呼函數。

   ```
   clientConnection: {
       connectionState: streamConnectionStateCallback,
       channelError: streamChannelErrorCallback,
       serverDisconnect: streamServerDisconnectCallback,
       applicationMessage: streamApplicationMessageCallback,
   }
   ```

1.  呼叫 `GameLiftStreams.sendApplicationMessage`函數以傳送訊息到您的應用程式。只要串流工作階段處於作用中狀態且已連接輸入，您就可以隨時呼叫此選項。

例如，請參閱 Amazon GameLift Streams Web SDK 範例用戶端，其示範如何在用戶端設定簡單的資料通道。

## 在應用程式端
<a name="data-channels-using-application"></a>

在您的應用程式中寫入下列邏輯。

### 步驟 1. 連接至資料通道連接埠
<a name="data-channels-using-application-1"></a>

當您的應用程式啟動時，請連線至 `40712`上的連接埠`localhost`。您的應用程式應該在整個執行期間維持此連線。如果應用程式關閉連線，則無法重新開啟。

### 步驟 2. 接聽事件
<a name="data-channels-using-application-2"></a>

事件以固定大小的標頭開頭，後面接著變數長度的相關資料。當您的應用程式收到事件時，請剖析事件以擷取資訊。

**事件格式**
+ **標頭**：表單中的 4 位元組標頭 `abcc`
  +  `a` ：用戶端 ID 位元組。在多個連線的情況下 （由於中斷連線和重新連線），這會識別特定的用戶端連線。
  +  `b` ：事件類型位元組。 `0` - 用戶端已連線， `1` - 用戶端已中斷連線， `2` - 從用戶端傳送訊息。其他事件類型可能會在未來的 Amazon GameLift Streams 服務更新時收到，應予以忽略。
  +  `cc` ：相關聯事件資料的長度。這表示為具有大端排序的 2 個位元組 （第一個位元組是最重要的）。如果事件類型為 2，則事件資料代表來自用戶端的訊息內容。
+ **資料**：剩餘的位元組包含事件資料，例如用戶端訊息。資料的長度由 `cc`標頭中的 表示。

**接聽事件**

1. 讀取四個標頭位元組，以擷取事件資料的用戶端 ID、事件類型和長度。

1. 根據 標頭中所述的長度，讀取可變長度事件資料，無論用戶端 ID 和事件類型為何。無條件讀取資料非常重要，這樣事件資料就永遠不會保留在緩衝區中，因為這可能會與下一個事件標頭混淆。請勿根據事件類型來假設資料的長度。

1. 如果您的應用程式辨識出 ，請根據事件類型採取適當的動作。此動作可能包括記錄傳入連線或中斷連線，或剖析用戶端訊息並觸發應用程式邏輯。

### 步驟 3。將訊息傳輸到用戶端
<a name="data-channels-using-application-3"></a>

應用程式應該使用傳入事件所使用的相同四位元組標頭格式來傳輸訊息。

**將訊息傳輸至用戶端**

1. 使用下列屬性撰寫 標頭：

   1. `a` ：用戶端 ID 位元組。如果您的訊息是回應用戶端訊息，則應該重複使用與傳入用戶端訊息相同的用戶端 ID，以避免競爭條件，例如從舊用戶端連線將回應傳送到新重新連線的用戶端。如果您的應用程式傳送未經要求的訊息給用戶端，則應將用戶端 ID 設定為符合最新的「用戶端連線」事件 （事件類型 0)。

   1. `b` ：傳出訊息的事件類型必須一律為 2。用戶端會忽略其他事件類型的訊息。

   1. `cc` ：訊息的長度，以位元組為單位。

1. 寫入訊息位元組。

除非用戶端中斷連線，否則訊息會傳送到指定的用戶端。中斷連線的用戶端重新連線時，會透過用戶端連線事件指派新的用戶端 ID。會捨棄舊用戶端 ID 的任何未交付訊息。

**Example**  
下列虛擬程式碼示範在應用程式端傳送訊息的邏輯。如需使用 Winsock 的完整範例，請參閱 Windows Sockets 2 文件中[的完整 Winsock 用戶端程式碼](https://learn.microsoft.com/en-us/windows/win32/winsock/complete-client-code)。  

```
connection = connect_to_tcp_socket("localhost:40712")
loop:
    while has_pending_bytes(connection):
        client_id = read_unsigned_byte(connection)
        event_type = read_unsigned_byte(connection)
        event_length = 256 * read_unsigned_byte(connection)
        event_length = event_length + read_unsigned_byte(connection)
        event_data = read_raw_bytes(connection, event_length)
        if message_type == 0:
            app_process_client_connected(client_id)
        else if message_type == 1:
            app_process_client_disconnected(client_id)
        else if message_type == 2:
            app_process_client_message(client_id, event_data)
        else:
            log("ignoring unrecognized event type")
    while app_has_outgoing_messages():
        target_client_id, message_bytes = app_next_outgoing_message()
        message_length = length(message_bytes)
        write_unsigned_byte(connection, target_client_id)
        write_unsigned_byte(connection, 2)
        write_unsigned_byte(connection, message_length / 256)
        write_unsigned_byte(connection, message_length mod 256)
        write_raw_bytes(connection, message_bytes)
```