

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

# Amazon DCV Web 用戶端 SDK 入門
開始使用

 Amazon DCV Web 用戶端 SDK 包含主要`dcv.js`檔案和一些輔助元件。所有檔案都會分佈在壓縮封存中，可從 [Amazon DCV 網站](https://download.nice-dcv.com/webclientsdk.html) 下載。

**開始使用 Amazon DCV Web 用戶端 SDK**

1. Amazon DCV Web 用戶端 SDK 封存會使用安全的 GPG 簽章進行數位簽署。若要驗證封存的簽章，您必須匯入 NICE GPG 金鑰。若要這樣做，請開啟終端機視窗並匯入 NICE GPG 金鑰。

   ```
   $ wget https://d1uj6qtbmh3dt5.cloudfront.net/NICE-GPG-KEY
   ```

   ```
   $ gpg --import NICE-GPG-KEY
   ```

1.  從 **Amazon DCV 網站 下載 Amazon DCV Web 用戶端 SDK 封存**[https://download.nice-dcv.com/webclientsdk.html](https://download.nice-dcv.com/webclientsdk.html)**和 Amazon DCV Web 用戶端 SDK 封存簽章**。

1. 使用簽章驗證 Amazon DCV Web 用戶端 SDK 封存的簽章。

   ```
   				$ gpg --verify
   				signature_filename.zip.sign
   				archive_filename.zip
   ```

   例如：

   ```
   $ gpg --verify nice-dcv-web-client-sdk-1.10.1-1011.zip.sign nice-dcv-web-client-sdk-1.10.1-1011.zip
   ```

1. 如果簽章驗證成功，請擷取 Amazon DCV Web 用戶端 SDK 封存的內容，並將擷取的目錄放在 Web 伺服器上。例如：

   ```
   				$ unzip
   				archive_filename.zip
   				-d /
   				path_to
   				/
   				server_directory
   				/
   ```
**重要**  
在 Web 伺服器上部署 Amazon DCV Web 用戶端 SDK 時，您必須保留 資料夾結構。
使用 Amazon DCV Web UI SDK 時，請注意 `DCVViewer` React 元件預期來自此套件的 EULA.txt third-party-licenses.txt 檔案會出現在內嵌 Web 伺服器的 URL 路徑中。third-party-licenses.txt 檔案也應該修改為包含來自 Amazon DCV Web 用戶端 SDK 套件的對應檔案內容，以及可能來自耗用使用者應用程式所用程式庫的任何其他授權資訊。

# 連線至 Amazon DCV 伺服器並取得第一個影格


下列教學課程說明如何為自訂 Web 用戶端準備 HTML 頁面、如何驗證和連線至 Amazon DCV 伺服器，以及如何從 Amazon DCV 工作階段接收串流內容的第一個影格。

**Topics**
+ [

## 步驟 1：準備您的 HTML 頁面
](#prep-html)
+ [

## 步驟 2：驗證、連線和取得第一個影格
](#auth-conn)
+ [

## 獎勵：自動建立 HTML 登入表單
](#get-token)

## 步驟 1：準備您的 HTML 頁面


 在您的網頁中，您必須載入所需的 JavaScript 模組，而且您必須新增 `<div>` HTML 元素，其中包含您希望 Amazon DCV Web 用戶端 SDK 從遠端 Amazon DCV 伺服器繪製內容串流的有效`id`位置。

例如：

```
<!DOCTYPE html>
<html lang="en" style="height: 100%;">
  <head>
    <title>DCV first connection</title>
  </head>
  <body style="height: 100%;">
    <div id="root" style="height: 100%;"></div>
    <div id="dcv-display"></div>
    <script type="module" src="index.js"></script>
  </body>
</html>
```

## 步驟 2：驗證、連線和取得第一個影格


本節說明如何完成使用者身分驗證程序、如何連接 Amazon DCV 伺服器，以及如何從 Amazon DCV 伺服器接收第一個內容影格。

 首先，從 `index.js` 檔案匯入 Amazon DCV Web 用戶端 SDK。它可以匯入為通用模組定義 (UMD) 模組，如下所示：

```
import "./dcvjs/dcv.js"
```

 否則，從版本 開始`1.1.0`，也可以從對應的套件匯入為 ECMAScript 模組 (ESM)，如下所示：

```
import dcv from "./dcvjs/dcv.js"
```

定義用來存放身分驗證物件、連線物件和 Amazon DCV 伺服器 URL 的變數。

```
let auth,
    connection,
    serverUrl;
```

 在指令碼載入時，記錄 Amazon DCV Web 用戶端 SDK 版本，並在頁面載入時呼叫 `main`函數。

```
console.log("Using Amazon DCV Web Client SDK version " + dcv.version.versionStr);
document.addEventListener('DOMContentLoaded', main);
```

 `main` 函數會設定日誌層級並啟動身分驗證程序。

```
function main () {
  console.log("Setting log level to INFO");
  dcv.setLogLevel(dcv.LogLevel.INFO);

  serverUrl = "https://your-dcv-server-url:port/";

  console.log("Starting authentication with", serverUrl);

  auth = dcv.authenticate(
    serverUrl,
    {
      promptCredentials: onPromptCredentials,
      error: onError,
      success: onSuccess
    }
  );
}
```

 、 `error` 和 `promptCredentials` `success`函數是必須在身分驗證程序中定義的強制性回呼函數。

 如果 Amazon DCV 伺服器提示登入資料，回`promptCredentials`呼函數會從 Amazon DCV 伺服器收到請求的登入資料挑戰。如果 Amazon DCV 伺服器設定為使用系統身分驗證，則必須提供登入憑證。下列程式碼範例假設使用者名稱為 ，`my_dcv_user`密碼為 `my_password`。

 如果身分驗證失敗，回`error`呼函數會從 Amazon DCV 伺服器接收錯誤物件。

 如果身分驗證成功，回`success`呼函數會接收包含工作階段 ID () `sessionId` 和授權字符 (`authToken`) 的耦合陣列，以供`my_dcv_user`使用者在 Amazon DCV 伺服器上連線到每個工作階段。下列程式碼範例會呼叫連線函數，並連線到陣列中傳回的第一個工作階段。

**注意**  
在下列程式碼範例中，將 取代`MY_DCV_USER`為您自己的使用者名稱，並將 `MY_PASSWORD`取代為您自己的密碼。

```
function onPromptCredentials(auth, challenge) {
  // Let's check if in challege we have a username and password request
  if (challengeHasField(challenge, "username") && challengeHasField(challenge, "password")) {
    auth.sendCredentials({username: MY_DCV_USER, password: MY_PASSWORD})
  } else {
    // Challenge is requesting something else...
  }
}

function challengeHasField(challenge, field) {
  return challenge.requiredCredentials.some(credential => credential.name === field);
}

function onError(auth, error) {
  console.log("Error during the authentication: " + error.message);
}

// We connect to the first session returned
function onSuccess(auth, result) {
  let {sessionId, authToken} = {...result[0]};

  connect(sessionId, authToken);
}
```

 連線至 Amazon DCV 伺服器。從 Amazon DCV 伺服器接收第一個影格時，呼叫回`firstFrame`呼方法。

```
function connect (sessionId, authToken) {
  console.log(sessionId, authToken);

  dcv.connect({
    url: serverUrl,
    sessionId: sessionId,
    authToken: authToken,
    divId: "dcv-display",
    callbacks: {
      firstFrame: () => console.log("First frame received")
    }
  }).then(function (conn) {
    console.log("Connection established!");
    connection= conn;
  }).catch(function (error) {
    console.log("Connection failed with error " + error.message);
  });
}
```

## 獎勵：自動建立 HTML 登入表單


 呼叫回`promptCredentials`呼函數時，會傳回`challenge`物件。它包含名為 `requiredCredentials` 物件陣列的 屬性 - Amazon DCV 伺服器請求的每個登入資料一個物件。每個物件都包含請求的登入資料的名稱和類型。您可以使用 `challenge`和 `requiredCredentials` 物件自動建立 HTML 登入表單。

下列程式碼範例示範如何執行此操作。

```
let form,
    fieldSet;

function submitCredentials (e) {
  var credentials = {};
  fieldSet.childNodes.forEach(input => credentials[input.id] = input.value);
  auth.sendCredentials(credentials);
  e.preventDefault();
}

function createLoginForm () {
  var submitButton = document.createElement("button");

  submitButton.type = "submit";
  submitButton.textContent = "Login";

  form = document.createElement("form");
  fieldSet = document.createElement("fieldset");

  form.onsubmit = submitCredentials;
  form.appendChild(fieldSet);
  form.appendChild(submitButton);

  document.body.appendChild(form);
}

function addInput (name) {
  var type = name === "password" ? "password" : "text";

  var inputField = document.createElement("input");
  inputField.name = name;
  inputField.id = name;
  inputField.placeholder = name;
  inputField.type = type;
  fieldSet.appendChild(inputField);
}

function onPromptCredentials (_, credentialsChallenge) {
  createLoginForm();
  credentialsChallenge.requiredCredentials.forEach(challenge => addInput(challenge.name));
}
```

# 使用 Amazon DCV 功能


Amazon DCV 功能的可用性取決於為 Amazon DCV 工作階段設定的許可，以及用戶端 Web 瀏覽器的功能。

 Amazon DCV 工作階段中可用的功能是由為工作階段指定的許可進行管理。這表示即使 Amazon DCV Web 用戶端 SDK 支援某項功能，根據工作階段管理員定義的許可，仍可能會阻止存取該功能。如需詳細資訊，請參閱《[Amazon DCV 管理員指南》中的設定 Amazon DCV 授權](https://docs.aws.amazon.com/dcv/latest/adminguide/security-authorization.html)。 **

## 了解 featuresUpdate 回呼函數


 當 Amazon DCV 工作階段中的功能可用性變更時，Amazon DCV Web 用戶端 SDK 會使用您在建立連線時指定的回`featuresUpdate`呼函數來通知您。例如：

```
featuresUpdate: function (connection, list) {
  ...
},
```

 回呼函數只會通知您可用性已變更的功能。`list` 參數是字串的陣列，而且只包含已更新功能的名稱。例如，如果工作階段的音訊輸入功能的可用性變更， 參數只會包含 `["audio-in"]` 。如果稍後，剪貼簿複製和貼上功能的可用性會變更工作階段，則 參數只會包含 `["clipboard-copy", "clipboard-paste"]` 。

## 處理功能更新


 回`featuresUpdate`呼函數只會通知您一或多個功能的可用性已變更。若要了解哪些功能已更新，您必須使用 `connection.queryFeature`方法查詢該功能。這可以在收到變更通知後隨時完成。此方法傳回`Promise`解析為請求功能更新狀態的 。該`status`值一律相關聯，且具有名為 `enabled` 的布林值 ( `true` \$1 `false` ) 屬性。某些功能在 `status`值中可能會有其他屬性。如果功能的可用性尚未更新，則會遭到拒絕。

下列範例程式碼示範如何執行此操作。

```
// Connection callback called
function featuresUpdate (_, list) {
  if (list.length > 0) {
    list.forEach((feat) => {
      connection.queryFeature(feat).then(status => console.log(feat, "is", status.enabled)));
    });
  }
}
```

# 使用 Amazon DCV Web UI SDK


 下列教學課程說明如何向 Amazon DCV 伺服器進行身分驗證、連接至該伺服器，以及從 Amazon DCV Web UI SDK 轉譯 `DCVViewer` React 元件。

**Topics**
+ [

## 先決條件
](#prerequisites)
+ [

## 步驟 1：準備您的 HTML 頁面
](#prep-html-ui)
+ [

## 步驟 2：驗證、連接和轉譯 `DCVViewer` React 元件。
](#auth-conn-render)
+ [

## 從 AWS-UI 更新至 Cloudscape 設計系統
](#updateawsuitocloudscape)

## 先決條件


 您需要安裝 `React` 、、 `ReactDOM` `Cloudscape Design Components React` `Cloudscape Design Global Styles`和 `Cloudscape Design Design Tokens` 。

```
$ npm i react react-dom @cloudscape-design/components @cloudscape-design/global-styles @cloudscape-design/design-tokens
```

 您也需要下載 `Amazon DCV Web Client SDK` 。請參閱 [Amazon DCV Web 用戶端 SDK 入門](getting-started.md)以閱讀如何執行此操作的step-by-step指南。

您必須建立用於匯入`dcv`模組的別名，因為它是 Amazon DCV Web UI SDK 的外部相依性。例如，如果您使用 webpack 綁定 Web 應用程式，您可以使用 [ resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias) 選項，如下所示：

```
const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      dcv: path.resolve('path', 'to', 'dcv.js'),
    },
  },
};
```

如果您使用彙總進行綁定，您可以安裝 [ @rollup/plugin-alias](https://www.npmjs.com/package/@rollup/plugin-alias)，並像這樣使用：

```
import alias from '@rollup/plugin-alias';
const path = require('path');

module.exports = {
  //...
  plugins: [
    alias({
      entries: [
        { find: 'dcv', replacement: path.resolve('path', 'to', 'dcv.js') },
      ]
    })
  ]
};
```

## 步驟 1：準備您的 HTML 頁面


 在您的網頁中，您必須載入必要的 JavaScript 模組，而且應該有一個 `<div>` HTML 元素，其中包含一個有效的 `id` HTML 元素，其中會轉譯您應用程式的進入元件。

例如：

```
<!DOCTYPE html>
<html lang="en" style="height: 100%;">
  <head>
    <title>DCV first connection</title>
  </head>
  <body style="height: 100%;">
    <div id="root" style="height: 100%;"></div>
    <script type="module" src="index.js"></script>
  </body>
</html>
```

## 步驟 2：驗證、連接和轉譯 `DCVViewer` React 元件。


 本節說明如何完成使用者身分驗證程序、如何連接 Amazon DCV 伺服器，以及如何轉譯 `DCVViewer` React 元件。

 首先，從 `index.js` 檔案匯入 `React` `ReactDOM`和您的頂層`App`元件。

```
import React from "react";
import ReactDOM from 'react-dom';
import App from './App';
```

轉譯應用程式的頂層容器節點。

```
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);
```

 在 `App.js` 檔案中，匯入 Amazon DCV Web 用戶端 SDK 做為 ESM 模組、Amazon DCV Web UI SDK 的 `DCVViewer` React 元件，`React`以及 `Cloudscape Design Global Styles`套件。

```
import React from "react";
import dcv from "dcv";
import "@cloudscape-design/global-styles/index.css";
import {DCVViewer} from "./dcv-ui/dcv-ui.js";
```

 以下範例示範如何在身分驗證成功的情況下，對 Amazon DCV 伺服器進行身分驗證，並從 Amazon DCV Web UI SDK 轉譯 `DCVViewer` React 元件。

```
const LOG_LEVEL = dcv.LogLevel.INFO;
const SERVER_URL = "https://your-dcv-server-url:port/";
const BASE_URL = "/static/js/dcvjs";

let auth;

function App() {
  const [authenticated, setAuthenticated] = React.useState(false);
  const [sessionId, setSessionId] = React.useState('');
  const [authToken, setAuthToken] = React.useState('');
  const [credentials, setCredentials] = React.useState({});

  const onSuccess = (_, result) => {
    var { sessionId, authToken } = { ...result[0] };

    console.log("Authentication successful.");

    setSessionId(sessionId);
    setAuthToken(authToken);
    setAuthenticated(true);
    setCredentials({});
  }

  const onPromptCredentials = (_, credentialsChallenge) => {
    let requestedCredentials = {};

    credentialsChallenge.requiredCredentials.forEach(challenge => requestedCredentials[challenge.name] = "");
    setCredentials(requestedCredentials);
  }

  const authenticate = () => {
    dcv.setLogLevel(LOG_LEVEL);

    auth = dcv.authenticate(
      SERVER_URL,
      {
        promptCredentials: onPromptCredentials,
        error: onError,
        success: onSuccess
      }
    );
  }

  const updateCredentials = (e) => {
    const { name, value } = e.target;
    setCredentials({
      ...credentials,
      [name]: value
    });
  }

  const submitCredentials = (e) => {
    auth.sendCredentials(credentials);
    e.preventDefault();
  }

  React.useEffect(() => {
    if (!authenticated) {
      authenticate();
    }
  }, [authenticated]);

  const handleDisconnect = (reason) => {
    console.log("Disconnected: " + reason.message + " (code: " + reason.code + ")");
    auth.retry();
    setAuthenticated(false);
  }

  return (
    authenticated ?
    <DCVViewer
      dcv={{
        sessionId: sessionId,
        authToken: authToken,
        serverUrl: SERVER_URL,
        baseUrl: BASE_URL,
        onDisconnect: handleDisconnect,
        logLevel: LOG_LEVEL
      }}
      uiConfig={{
        toolbar: {
          visible: true,
          fullscreenButton: true,
          multimonitorButton: true,
        },
      }}
    />
    :
    <div
      style={{
        height: window.innerHeight,
        backgroundColor: "#373737",
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      <form>
        <fieldset>
          {Object.keys(credentials).map((cred) => (
            <input
              key={cred}
              name={cred}
              placeholder={cred}
              type={cred === "password" ? "password" : "text"}
              onChange={updateCredentials}
              value={credentials[cred]}
            />
          ))}
        </fieldset>
        <button
          type="submit"
          onClick={submitCredentials}
        >
          Login
        </button>
      </form>
    </div>
  );
}

const onError = (_, error) => {
  console.log("Error during the authentication: " + error.message);
}

export default App;
```

 、 `error` 和 `promptCredentials` `success`函數是必須在身分驗證程序中定義的強制性回呼函數。

 如果 Amazon DCV 伺服器提示登入資料，回`promptCredentials`呼函數會從 Amazon DCV 伺服器收到請求的登入資料挑戰。如果 Amazon DCV 伺服器設定為使用系統身分驗證，則必須以使用者名稱和密碼的形式提供憑證。

 如果身分驗證失敗，回`error`呼函數會從 Amazon DCV 伺服器接收錯誤物件。

 如果身分驗證成功，回`success`呼函數會接收包含工作階段 ID () `sessionId` 和授權字符 (`authToken`) 的耦合陣列，以供使用者在 Amazon DCV 伺服器上連線到每個工作階段。上述程式碼範例會更新 React 狀態，以在身分驗證成功時轉譯`DCVViewer`元件。

 若要進一步了解此元件接受的屬性，請參閱 [ Amazon DCV Web UI SDK 參考](https://docs.aws.amazon.com/dcv/latest/websdkguide/dcv-viewer.html#DCVViewer)。

 若要進一步了解自我簽署憑證，請參閱[自我簽署憑證的重新導向說明](https://docs.aws.amazon.com/dcv/latest/adminguide/redirection-clarifications-with-self-signed-certs.html)。

## 從 AWS-UI 更新至 Cloudscape 設計系統


 從 SDK 1.3.0 版開始，我們將`DCVViewer`元件從 AWS-UI 更新至其演變：[Cloudscape Design](https://cloudscape.design/)。

 Cloudscape 使用與 AWS-UI 不同的視覺化佈景主題，但基礎程式碼基礎保持不變。因此，根據 遷移應用程式`DCVViewer`應該很簡單。若要遷移，請將您安裝的 AWS-UI 相關 NPM 套件取代為相關聯的 Cloudscape 套件：


| AWS-UI 套件名稱 | Cloudscape 套件名稱 | 
| --- | --- | 
| @awsui/components-react | @cloudscape-design/元件 | 
| @awsui/全域樣式 | @cloudscape-design/全域樣式 | 
| @awsui/collection-hooks | @cloudscape-design/collection-hooks | 
| @awsui/design-tokens | @cloudscape-design/design-tokens | 

 如需遷移的詳細資訊，請參閱 [AWS-UI GitHub 文件頁面](https://github.com/aws/awsui-documentation)。